Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * NetLabel CIPSO/IPv4 Support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * This file defines the CIPSO/IPv4 functions for the NetLabel system.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * NetLabel system manages static and dynamic label mappings for network
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * protocols such as CIPSO and RIPSO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Author: Paul Moore <paul@paul-moore.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <net/netlabel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <net/cipso_ipv4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include "netlabel_user.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "netlabel_cipso_v4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include "netlabel_mgmt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include "netlabel_domainhash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /* Argument struct for cipso_v4_doi_walk() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) struct netlbl_cipsov4_doiwalk_arg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	struct netlink_callback *nl_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	u32 seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) /* Argument struct for netlbl_domhsh_walk() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) struct netlbl_domhsh_walk_arg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	struct netlbl_audit *audit_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	u32 doi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /* NetLabel Generic NETLINK CIPSOv4 family */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static struct genl_family netlbl_cipsov4_gnl_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) /* NetLabel Netlink attribute policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	[NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	[NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	[NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	[NLBL_CIPSOV4_A_TAGLST] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	[NLBL_CIPSOV4_A_MLSLVLLOC] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	[NLBL_CIPSOV4_A_MLSLVLREM] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	[NLBL_CIPSOV4_A_MLSLVL] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	[NLBL_CIPSOV4_A_MLSLVLLST] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	[NLBL_CIPSOV4_A_MLSCATLOC] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	[NLBL_CIPSOV4_A_MLSCATREM] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	[NLBL_CIPSOV4_A_MLSCAT] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	[NLBL_CIPSOV4_A_MLSCATLST] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * Helper Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * netlbl_cipsov4_add_common - Parse the common sections of a ADD message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * @doi_def: the CIPSO V4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * Parse the common sections of a ADD message and fill in the related values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * in @doi_def.  Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static int netlbl_cipsov4_add_common(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 				     struct cipso_v4_doi *doi_def)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	int nla_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	u32 iter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	doi_def->doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (nla_validate_nested_deprecated(info->attrs[NLBL_CIPSOV4_A_TAGLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 					   NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 					   netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 					   NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	nla_for_each_nested(nla, info->attrs[NLBL_CIPSOV4_A_TAGLST], nla_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		if (nla_type(nla) == NLBL_CIPSOV4_A_TAG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			if (iter >= CIPSO_V4_TAG_MAXCNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			doi_def->tags[iter++] = nla_get_u8(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	while (iter < CIPSO_V4_TAG_MAXCNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		doi_def->tags[iter++] = CIPSO_V4_TAG_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * NetLabel Command Handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * netlbl_cipsov4_add_std - Adds a CIPSO V4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * message and add it to the CIPSO V4 engine.  Return zero on success and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * non-zero on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static int netlbl_cipsov4_add_std(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 				  struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	int ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	struct cipso_v4_doi *doi_def = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	struct nlattr *nla_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	struct nlattr *nla_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	int nla_a_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	int nla_b_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	u32 iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	    !info->attrs[NLBL_CIPSOV4_A_MLSLVLLST])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (nla_validate_nested_deprecated(info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 					   NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 					   netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 					   NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	if (doi_def == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	doi_def->map.std = kzalloc(sizeof(*doi_def->map.std), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (doi_def->map.std == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		kfree(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	doi_def->type = CIPSO_V4_MAP_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	ret_val = netlbl_cipsov4_add_common(info, doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	nla_for_each_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			    info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			    nla_a_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			if (nla_validate_nested_deprecated(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 							   NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 							   netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 							   NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 				goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			nla_for_each_nested(nla_b, nla_a, nla_b_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 				switch (nla_type(nla_b)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 				case NLBL_CIPSOV4_A_MLSLVLLOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 					if (nla_get_u32(nla_b) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 					    CIPSO_V4_MAX_LOC_LVLS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 						goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 					if (nla_get_u32(nla_b) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 					    doi_def->map.std->lvl.local_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 					     doi_def->map.std->lvl.local_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 						     nla_get_u32(nla_b) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				case NLBL_CIPSOV4_A_MLSLVLREM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 					if (nla_get_u32(nla_b) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 					    CIPSO_V4_MAX_REM_LVLS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 						goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 					if (nla_get_u32(nla_b) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 					    doi_def->map.std->lvl.cipso_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 					     doi_def->map.std->lvl.cipso_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 						     nla_get_u32(nla_b) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 					      sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 					      GFP_KERNEL | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	if (doi_def->map.std->lvl.local == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	doi_def->map.std->lvl.cipso = kcalloc(doi_def->map.std->lvl.cipso_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 					      sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 					      GFP_KERNEL | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (doi_def->map.std->lvl.cipso == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	for (iter = 0; iter < doi_def->map.std->lvl.local_size; iter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		doi_def->map.std->lvl.local[iter] = CIPSO_V4_INV_LVL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	for (iter = 0; iter < doi_def->map.std->lvl.cipso_size; iter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		doi_def->map.std->lvl.cipso[iter] = CIPSO_V4_INV_LVL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	nla_for_each_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			    info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			    nla_a_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			struct nlattr *lvl_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			struct nlattr *lvl_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			lvl_loc = nla_find_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 						  NLBL_CIPSOV4_A_MLSLVLLOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			lvl_rem = nla_find_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 						  NLBL_CIPSOV4_A_MLSLVLREM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			if (lvl_loc == NULL || lvl_rem == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 				goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			doi_def->map.std->lvl.local[nla_get_u32(lvl_loc)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 				nla_get_u32(lvl_rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			doi_def->map.std->lvl.cipso[nla_get_u32(lvl_rem)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 				nla_get_u32(lvl_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (info->attrs[NLBL_CIPSOV4_A_MLSCATLST]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		if (nla_validate_nested_deprecated(info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 						   NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 						   netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 						   NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		nla_for_each_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 				    info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 				    nla_a_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 				if (nla_validate_nested_deprecated(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 								   NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 								   netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 								   NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 					goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 				nla_for_each_nested(nla_b, nla_a, nla_b_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 					switch (nla_type(nla_b)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 					case NLBL_CIPSOV4_A_MLSCATLOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 						if (nla_get_u32(nla_b) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 						    CIPSO_V4_MAX_LOC_CATS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 							goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 						if (nla_get_u32(nla_b) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 					      doi_def->map.std->cat.local_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 					     doi_def->map.std->cat.local_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 						     nla_get_u32(nla_b) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 					case NLBL_CIPSOV4_A_MLSCATREM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 						if (nla_get_u32(nla_b) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 						    CIPSO_V4_MAX_REM_CATS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 							goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 						if (nla_get_u32(nla_b) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 					      doi_def->map.std->cat.cipso_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 					     doi_def->map.std->cat.cipso_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 						     nla_get_u32(nla_b) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		doi_def->map.std->cat.local = kcalloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 					      doi_def->map.std->cat.local_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 					      sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 					      GFP_KERNEL | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		if (doi_def->map.std->cat.local == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 			ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		doi_def->map.std->cat.cipso = kcalloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 					      doi_def->map.std->cat.cipso_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 					      sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 					      GFP_KERNEL | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		if (doi_def->map.std->cat.cipso == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		for (iter = 0; iter < doi_def->map.std->cat.local_size; iter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			doi_def->map.std->cat.local[iter] = CIPSO_V4_INV_CAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		for (iter = 0; iter < doi_def->map.std->cat.cipso_size; iter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			doi_def->map.std->cat.cipso[iter] = CIPSO_V4_INV_CAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		nla_for_each_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 				    info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 				    nla_a_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 				struct nlattr *cat_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 				struct nlattr *cat_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 				cat_loc = nla_find_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 						     NLBL_CIPSOV4_A_MLSCATLOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 				cat_rem = nla_find_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 						     NLBL_CIPSOV4_A_MLSCATREM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 				if (cat_loc == NULL || cat_rem == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 					goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 				doi_def->map.std->cat.local[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 							nla_get_u32(cat_loc)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 					nla_get_u32(cat_rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 				doi_def->map.std->cat.cipso[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 							nla_get_u32(cat_rem)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 					nla_get_u32(cat_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	ret_val = cipso_v4_doi_add(doi_def, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) add_std_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	cipso_v4_doi_free(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)  * netlbl_cipsov4_add_pass - Adds a CIPSO V4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)  * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)  * Create a new CIPSO_V4_MAP_PASS DOI definition based on the given ADD message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)  * and add it to the CIPSO V4 engine.  Return zero on success and non-zero on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)  * error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static int netlbl_cipsov4_add_pass(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 				   struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	struct cipso_v4_doi *doi_def = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (doi_def == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	doi_def->type = CIPSO_V4_MAP_PASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	ret_val = netlbl_cipsov4_add_common(info, doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		goto add_pass_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	ret_val = cipso_v4_doi_add(doi_def, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		goto add_pass_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) add_pass_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	cipso_v4_doi_free(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  * Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)  * message and add it to the CIPSO V4 engine.  Return zero on success and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)  * non-zero on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int netlbl_cipsov4_add_local(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 				    struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	struct cipso_v4_doi *doi_def = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	if (doi_def == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	doi_def->type = CIPSO_V4_MAP_LOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	ret_val = netlbl_cipsov4_add_common(info, doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		goto add_local_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	ret_val = cipso_v4_doi_add(doi_def, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		goto add_local_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) add_local_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	cipso_v4_doi_free(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  * netlbl_cipsov4_add - Handle an ADD message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  * @skb: the NETLINK buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  * Create a new DOI definition based on the given ADD message and add it to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)  * CIPSO V4 engine.  Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	int ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	struct netlbl_audit audit_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	    !info->attrs[NLBL_CIPSOV4_A_MTYPE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	netlbl_netlink_auditinfo(skb, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	switch (nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	case CIPSO_V4_MAP_TRANS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		ret_val = netlbl_cipsov4_add_std(info, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	case CIPSO_V4_MAP_PASS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		ret_val = netlbl_cipsov4_add_pass(info, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	case CIPSO_V4_MAP_LOCAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		ret_val = netlbl_cipsov4_add_local(info, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	if (ret_val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		atomic_inc(&netlabel_mgmt_protocount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)  * netlbl_cipsov4_list - Handle a LIST message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)  * @skb: the NETLINK buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)  * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)  * Process a user generated LIST message and respond accordingly.  While the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)  * response message generated by the kernel is straightforward, determining
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)  * before hand the size of the buffer to allocate is not (we have to generate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)  * the message to know the size).  In order to keep this function sane what we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)  * do is allocate a buffer of NLMSG_GOODSIZE and try to fit the response in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)  * that size, if we fail then we restart with a larger buffer and try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)  * We continue in this manner until we hit a limit of failed attempts then we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)  * give up and just send an error message.  Returns zero on success and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)  * negative values on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int netlbl_cipsov4_list(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	struct sk_buff *ans_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	u32 nlsze_mult = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	u32 doi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	struct nlattr *nla_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	struct nlattr *nla_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	struct cipso_v4_doi *doi_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	u32 iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	if (!info->attrs[NLBL_CIPSOV4_A_DOI]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		goto list_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) list_start:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE * nlsze_mult, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	if (ans_skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		goto list_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	data = genlmsg_put_reply(ans_skb, info, &netlbl_cipsov4_gnl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 				 0, NLBL_CIPSOV4_C_LIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	if (data == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		goto list_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	doi_def = cipso_v4_doi_getdef(doi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	if (doi_def == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		goto list_failure_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	ret_val = nla_put_u32(ans_skb, NLBL_CIPSOV4_A_MTYPE, doi_def->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		goto list_failure_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	nla_a = nla_nest_start_noflag(ans_skb, NLBL_CIPSOV4_A_TAGLST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	if (nla_a == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		goto list_failure_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	for (iter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	     iter < CIPSO_V4_TAG_MAXCNT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	       doi_def->tags[iter] != CIPSO_V4_TAG_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	     iter++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		ret_val = nla_put_u8(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 				     NLBL_CIPSOV4_A_TAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 				     doi_def->tags[iter]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			goto list_failure_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	nla_nest_end(ans_skb, nla_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	switch (doi_def->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	case CIPSO_V4_MAP_TRANS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		nla_a = nla_nest_start_noflag(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 					      NLBL_CIPSOV4_A_MLSLVLLST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		if (nla_a == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 			ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 			goto list_failure_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		for (iter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		     iter < doi_def->map.std->lvl.local_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		     iter++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 			if (doi_def->map.std->lvl.local[iter] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			    CIPSO_V4_INV_LVL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			nla_b = nla_nest_start_noflag(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 						      NLBL_CIPSOV4_A_MLSLVL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 			if (nla_b == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 				ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 				goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 			ret_val = nla_put_u32(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 					      NLBL_CIPSOV4_A_MLSLVLLOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 					      iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 			if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 				goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			ret_val = nla_put_u32(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 					    NLBL_CIPSOV4_A_MLSLVLREM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 					    doi_def->map.std->lvl.local[iter]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 				goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			nla_nest_end(ans_skb, nla_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		nla_nest_end(ans_skb, nla_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		nla_a = nla_nest_start_noflag(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 					      NLBL_CIPSOV4_A_MLSCATLST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		if (nla_a == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 			ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 			goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		for (iter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		     iter < doi_def->map.std->cat.local_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		     iter++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 			if (doi_def->map.std->cat.local[iter] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 			    CIPSO_V4_INV_CAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 			nla_b = nla_nest_start_noflag(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 						      NLBL_CIPSOV4_A_MLSCAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 			if (nla_b == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 				ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 				goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 			ret_val = nla_put_u32(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 					      NLBL_CIPSOV4_A_MLSCATLOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 					      iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 			if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 				goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			ret_val = nla_put_u32(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 					    NLBL_CIPSOV4_A_MLSCATREM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 					    doi_def->map.std->cat.local[iter]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 				goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 			nla_nest_end(ans_skb, nla_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		nla_nest_end(ans_skb, nla_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	cipso_v4_doi_putdef(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	genlmsg_end(ans_skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	return genlmsg_reply(ans_skb, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) list_retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	/* XXX - this limit is a guesstimate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	if (nlsze_mult < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		cipso_v4_doi_putdef(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		kfree_skb(ans_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		nlsze_mult *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		goto list_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) list_failure_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	cipso_v4_doi_putdef(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) list_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	kfree_skb(ans_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)  * netlbl_cipsov4_listall_cb - cipso_v4_doi_walk() callback for LISTALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)  * @doi_def: the CIPSOv4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)  * @arg: the netlbl_cipsov4_doiwalk_arg structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)  * This function is designed to be used as a callback to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)  * cipso_v4_doi_walk() function for use in generating a response for a LISTALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)  * message.  Returns the size of the message on success, negative values on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)  * failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static int netlbl_cipsov4_listall_cb(struct cipso_v4_doi *doi_def, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	int ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	struct netlbl_cipsov4_doiwalk_arg *cb_arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 			   cb_arg->seq, &netlbl_cipsov4_gnl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 			   NLM_F_MULTI, NLBL_CIPSOV4_C_LISTALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		goto listall_cb_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	ret_val = nla_put_u32(cb_arg->skb, NLBL_CIPSOV4_A_DOI, doi_def->doi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		goto listall_cb_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	ret_val = nla_put_u32(cb_arg->skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 			      NLBL_CIPSOV4_A_MTYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 			      doi_def->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		goto listall_cb_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	genlmsg_end(cb_arg->skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) listall_cb_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	genlmsg_cancel(cb_arg->skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)  * netlbl_cipsov4_listall - Handle a LISTALL message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)  * @skb: the NETLINK buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)  * @cb: the NETLINK callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)  * Process a user generated LISTALL message and respond accordingly.  Returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)  * zero on success and negative values on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static int netlbl_cipsov4_listall(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 				  struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	struct netlbl_cipsov4_doiwalk_arg cb_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	u32 doi_skip = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	cb_arg.nl_cb = cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	cb_arg.skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	cb_arg.seq = cb->nlh->nlmsg_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	cipso_v4_doi_walk(&doi_skip, netlbl_cipsov4_listall_cb, &cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	cb->args[0] = doi_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)  * netlbl_cipsov4_remove_cb - netlbl_cipsov4_remove() callback for REMOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)  * @entry: LSM domain mapping entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)  * @arg: the netlbl_domhsh_walk_arg structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)  * This function is intended for use by netlbl_cipsov4_remove() as the callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)  * for the netlbl_domhsh_walk() function; it removes LSM domain map entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)  * which are associated with the CIPSO DOI specified in @arg.  Returns zero on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)  * success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	struct netlbl_domhsh_walk_arg *cb_arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	if (entry->def.type == NETLBL_NLTYPE_CIPSOV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	    entry->def.cipso->doi == cb_arg->doi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)  * netlbl_cipsov4_remove - Handle a REMOVE message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)  * @skb: the NETLINK buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)  * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)  * Process a user generated REMOVE message and respond accordingly.  Returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)  * zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	int ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	struct netlbl_domhsh_walk_arg cb_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	struct netlbl_audit audit_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	u32 skip_bkt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	u32 skip_chain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	if (!info->attrs[NLBL_CIPSOV4_A_DOI])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	netlbl_netlink_auditinfo(skb, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	cb_arg.doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	cb_arg.audit_info = &audit_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 				     netlbl_cipsov4_remove_cb, &cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	if (ret_val == 0 || ret_val == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		ret_val = cipso_v4_doi_remove(cb_arg.doi, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		if (ret_val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 			atomic_dec(&netlabel_mgmt_protocount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)  * NetLabel Generic NETLINK Command Definitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static const struct genl_small_ops netlbl_cipsov4_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	.cmd = NLBL_CIPSOV4_C_ADD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	.doit = netlbl_cipsov4_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	.dumpit = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	.cmd = NLBL_CIPSOV4_C_REMOVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	.doit = netlbl_cipsov4_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	.dumpit = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	.cmd = NLBL_CIPSOV4_C_LIST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	.doit = netlbl_cipsov4_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	.dumpit = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	.cmd = NLBL_CIPSOV4_C_LISTALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	.doit = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	.dumpit = netlbl_cipsov4_listall,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static struct genl_family netlbl_cipsov4_gnl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	.hdrsize = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	.name = NETLBL_NLTYPE_CIPSOV4_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	.version = NETLBL_PROTO_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	.maxattr = NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	.policy = netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	.module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	.small_ops = netlbl_cipsov4_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	.n_small_ops = ARRAY_SIZE(netlbl_cipsov4_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)  * NetLabel Generic NETLINK Protocol Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)  * netlbl_cipsov4_genl_init - Register the CIPSOv4 NetLabel component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)  * Register the CIPSOv4 packet NetLabel component with the Generic NETLINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)  * mechanism.  Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) int __init netlbl_cipsov4_genl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	return genl_register_family(&netlbl_cipsov4_gnl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }