⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netlabel_cipso_v4.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
{	int ret_val = -EINVAL;	u32 type;	u32 doi;	const char *type_str = "(unknown)";	struct audit_buffer *audit_buf;	struct netlbl_audit audit_info;	if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||	    !info->attrs[NLBL_CIPSOV4_A_MTYPE])		return -EINVAL;	doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);	netlbl_netlink_auditinfo(skb, &audit_info);	type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);	switch (type) {	case CIPSO_V4_MAP_STD:		type_str = "std";		ret_val = netlbl_cipsov4_add_std(info);		break;	case CIPSO_V4_MAP_PASS:		type_str = "pass";		ret_val = netlbl_cipsov4_add_pass(info);		break;	}	if (ret_val == 0)		netlbl_mgmt_protocount_inc();	audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,					      &audit_info);	if (audit_buf != NULL) {		audit_log_format(audit_buf,				 " cipso_doi=%u cipso_type=%s res=%u",				 doi,				 type_str,				 ret_val == 0 ? 1 : 0);		audit_log_end(audit_buf);	}	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;	}	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(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_STD:		nla_a = nla_nest_start(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(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(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(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;	}	rcu_read_unlock();	genlmsg_end(ans_skb, data);	ret_val = genlmsg_reply(ans_skb, info);	if (ret_val != 0)		goto list_failure;	return 0;list_retry:	/* XXX - this limit is a guesstimate */	if (nlsze_mult < 4) {		rcu_read_unlock();		kfree_skb(ans_skb);		nlsze_mult++;		goto list_start;	}list_failure_lock:	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).pid,			   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;	return genlmsg_end(cb_arg->skb, data);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;	int 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 - 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;	u32 doi = 0;	struct audit_buffer *audit_buf;	struct netlbl_audit audit_info;	if (!info->attrs[NLBL_CIPSOV4_A_DOI])		return -EINVAL;	doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);	netlbl_netlink_auditinfo(skb, &audit_info);	ret_val = cipso_v4_doi_remove(doi,				      &audit_info,				      netlbl_cipsov4_doi_free);	if (ret_val == 0)		netlbl_mgmt_protocount_dec();	audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,					      &audit_info);	if (audit_buf != NULL) {		audit_log_format(audit_buf,				 " cipso_doi=%u res=%u",				 doi,				 ret_val == 0 ? 1 : 0);		audit_log_end(audit_buf);	}	return ret_val;}/* * NetLabel Generic NETLINK Command Definitions */static struct genl_ops netlbl_cipsov4_genl_c_add = {	.cmd = NLBL_CIPSOV4_C_ADD,	.flags = GENL_ADMIN_PERM,	.policy = netlbl_cipsov4_genl_policy,	.doit = netlbl_cipsov4_add,	.dumpit = NULL,};static struct genl_ops netlbl_cipsov4_genl_c_remove = {	.cmd = NLBL_CIPSOV4_C_REMOVE,	.flags = GENL_ADMIN_PERM,	.policy = netlbl_cipsov4_genl_policy,	.doit = netlbl_cipsov4_remove,	.dumpit = NULL,};static struct genl_ops netlbl_cipsov4_genl_c_list = {	.cmd = NLBL_CIPSOV4_C_LIST,	.flags = 0,	.policy = netlbl_cipsov4_genl_policy,	.doit = netlbl_cipsov4_list,	.dumpit = NULL,};static struct genl_ops netlbl_cipsov4_genl_c_listall = {	.cmd = NLBL_CIPSOV4_C_LISTALL,	.flags = 0,	.policy = netlbl_cipsov4_genl_policy,	.doit = NULL,	.dumpit = netlbl_cipsov4_listall,};/* * 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 netlbl_cipsov4_genl_init(void){	int ret_val;	ret_val = genl_register_family(&netlbl_cipsov4_gnl_family);	if (ret_val != 0)		return ret_val;	ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,				    &netlbl_cipsov4_genl_c_add);	if (ret_val != 0)		return ret_val;	ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,				    &netlbl_cipsov4_genl_c_remove);	if (ret_val != 0)		return ret_val;	ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,				    &netlbl_cipsov4_genl_c_list);	if (ret_val != 0)		return ret_val;	ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,				    &netlbl_cipsov4_genl_c_listall);	if (ret_val != 0)		return ret_val;	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -