// SPDX-License-Identifier: GPL-2.0-or-later /* * NetLabel Management Support * * This file defines the management 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>
*/
/** * netlbl_mgmt_add_common - Handle an ADD message * @info: the Generic NETLINK info block * @audit_info: NetLabel audit information * * Description: * Helper function for the ADD and ADDDEF messages to add the domain mappings * from the message to the hash table. See netlabel.h for a description of the * message format. Returns zero on success, negative values on failure. *
*/ staticint netlbl_mgmt_add_common(struct genl_info *info, struct netlbl_audit *audit_info)
{ void *pmap = NULL; int ret_val = -EINVAL; struct netlbl_domaddr_map *addrmap = NULL; struct cipso_v4_doi *cipsov4 = NULL; #if IS_ENABLED(CONFIG_IPV6) struct calipso_doi *calipso = NULL; #endif
u32 tmp_val; struct netlbl_dom_map *entry = kzalloc(sizeof(*entry), GFP_KERNEL);
/* NOTE: internally we allow/use a entry->def.type value of * NETLBL_NLTYPE_ADDRSELECT but we don't currently allow users * to pass that as a protocol value because we need to know the
* "real" protocol */
switch (entry->def.type) { case NETLBL_NLTYPE_UNLABELED:
entry->family =
nla_get_u16_default(info->attrs[NLBL_MGMT_A_FAMILY],
AF_UNSPEC); break; case NETLBL_NLTYPE_CIPSOV4: if (!info->attrs[NLBL_MGMT_A_CV4DOI]) goto add_free_domain;
tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]);
cipsov4 = cipso_v4_doi_getdef(tmp_val); if (cipsov4 == NULL) goto add_free_domain;
entry->family = AF_INET;
entry->def.cipso = cipsov4; break; #if IS_ENABLED(CONFIG_IPV6) case NETLBL_NLTYPE_CALIPSO: if (!info->attrs[NLBL_MGMT_A_CLPDOI]) goto add_free_domain;
/** * netlbl_mgmt_listentry - List a NetLabel/LSM domain map entry * @skb: the NETLINK buffer * @entry: the map entry * * Description: * This function is a helper function used by the LISTALL and LISTDEF command * handlers. The caller is responsible for ensuring that the RCU read lock * is held. Returns zero on success, negative values on failure. *
*/ staticint netlbl_mgmt_listentry(struct sk_buff *skb, struct netlbl_dom_map *entry)
{ int ret_val = 0; struct nlattr *nla_a; struct nlattr *nla_b; struct netlbl_af4list *iter4; #if IS_ENABLED(CONFIG_IPV6) struct netlbl_af6list *iter6; #endif
if (entry->domain != NULL) {
ret_val = nla_put_string(skb,
NLBL_MGMT_A_DOMAIN, entry->domain); if (ret_val != 0) return ret_val;
}
switch (map6->def.type) { case NETLBL_NLTYPE_CALIPSO:
ret_val = nla_put_u32(skb, NLBL_MGMT_A_CLPDOI,
map6->def.calipso->doi); if (ret_val != 0) return ret_val; break;
}
nla_nest_end(skb, nla_b);
} #endif/* IPv6 */
nla_nest_end(skb, nla_a); break; case NETLBL_NLTYPE_UNLABELED:
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
entry->def.type); break; case NETLBL_NLTYPE_CIPSOV4:
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
entry->def.type); if (ret_val != 0) return ret_val;
ret_val = nla_put_u32(skb, NLBL_MGMT_A_CV4DOI,
entry->def.cipso->doi); break; case NETLBL_NLTYPE_CALIPSO:
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
entry->def.type); if (ret_val != 0) return ret_val;
ret_val = nla_put_u32(skb, NLBL_MGMT_A_CLPDOI,
entry->def.calipso->doi); break;
}
return ret_val;
}
/* * NetLabel Command Handlers
*/
/** * netlbl_mgmt_add - Handle an ADD message * @skb: the NETLINK buffer * @info: the Generic NETLINK info block * * Description: * Process a user generated ADD message and add the domains from the message * to the hash table. See netlabel.h for a description of the message format. * Returns zero on success, negative values on failure. *
*/ staticint netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
{ struct netlbl_audit audit_info;
/** * netlbl_mgmt_remove - Handle a REMOVE message * @skb: the NETLINK buffer * @info: the Generic NETLINK info block * * Description: * Process a user generated REMOVE message and remove the specified domain * mappings. Returns zero on success, negative values on failure. *
*/ staticint netlbl_mgmt_remove(struct sk_buff *skb, struct genl_info *info)
{ char *domain; struct netlbl_audit audit_info;
if (!info->attrs[NLBL_MGMT_A_DOMAIN]) return -EINVAL;
/** * netlbl_mgmt_listall_cb - netlbl_domhsh_walk() callback for LISTALL * @entry: the domain mapping hash table entry * @arg: the netlbl_domhsh_walk_arg structure * * Description: * This function is designed to be used as a callback to the * netlbl_domhsh_walk() function for use in generating a response for a LISTALL * message. Returns the size of the message on success, negative values on * failure. *
*/ staticint netlbl_mgmt_listall_cb(struct netlbl_dom_map *entry, void *arg)
{ int ret_val = -ENOMEM; struct netlbl_domhsh_walk_arg *cb_arg = arg; void *data;
data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
cb_arg->seq, &netlbl_mgmt_gnl_family,
NLM_F_MULTI, NLBL_MGMT_C_LISTALL); if (data == NULL) goto listall_cb_failure;
ret_val = netlbl_mgmt_listentry(cb_arg->skb, entry); if (ret_val != 0) goto listall_cb_failure;
/** * netlbl_mgmt_listall - Handle a LISTALL message * @skb: the NETLINK buffer * @cb: the NETLINK callback * * Description: * Process a user generated LISTALL message and dumps the domain hash table in * a form suitable for use in a kernel generated LISTALL message. Returns zero * on success, negative values on failure. *
*/ staticint netlbl_mgmt_listall(struct sk_buff *skb, struct netlink_callback *cb)
{ struct netlbl_domhsh_walk_arg cb_arg;
u32 skip_bkt = cb->args[0];
u32 skip_chain = cb->args[1];
/** * netlbl_mgmt_adddef - Handle an ADDDEF message * @skb: the NETLINK buffer * @info: the Generic NETLINK info block * * Description: * Process a user generated ADDDEF message and respond accordingly. Returns * zero on success, negative values on failure. *
*/ staticint netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
{ struct netlbl_audit audit_info;
/** * netlbl_mgmt_removedef - Handle a REMOVEDEF message * @skb: the NETLINK buffer * @info: the Generic NETLINK info block * * Description: * Process a user generated REMOVEDEF message and remove the default domain * mapping. Returns zero on success, negative values on failure. *
*/ staticint netlbl_mgmt_removedef(struct sk_buff *skb, struct genl_info *info)
{ struct netlbl_audit audit_info;
/** * netlbl_mgmt_listdef - Handle a LISTDEF message * @skb: the NETLINK buffer * @info: the Generic NETLINK info block * * Description: * Process a user generated LISTDEF message and dumps the default domain * mapping in a form suitable for use in a kernel generated LISTDEF message. * Returns zero on success, negative values on failure. *
*/ staticint netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info)
{ int ret_val = -ENOMEM; struct sk_buff *ans_skb = NULL; void *data; struct netlbl_dom_map *entry;
u16 family;
family = nla_get_u16_default(info->attrs[NLBL_MGMT_A_FAMILY], AF_INET);
ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (ans_skb == NULL) return -ENOMEM;
data = genlmsg_put_reply(ans_skb, info, &netlbl_mgmt_gnl_family,
0, NLBL_MGMT_C_LISTDEF); if (data == NULL) goto listdef_failure;
/** * netlbl_mgmt_protocols_cb - Write an individual PROTOCOL message response * @skb: the skb to write to * @cb: the NETLINK callback * @protocol: the NetLabel protocol to use in the message * * Description: * This function is to be used in conjunction with netlbl_mgmt_protocols() to * answer a application's PROTOCOLS message. Returns the size of the message * on success, negative values on failure. *
*/ staticint netlbl_mgmt_protocols_cb(struct sk_buff *skb, struct netlink_callback *cb,
u32 protocol)
{ int ret_val = -ENOMEM; void *data;
data = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
&netlbl_mgmt_gnl_family, NLM_F_MULTI,
NLBL_MGMT_C_PROTOCOLS); if (data == NULL) goto protocols_cb_failure;
/** * netlbl_mgmt_version - Handle a VERSION message * @skb: the NETLINK buffer * @info: the Generic NETLINK info block * * Description: * Process a user generated VERSION message and respond accordingly. Returns * zero on success, negative values on failure. *
*/ staticint netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info)
{ int ret_val = -ENOMEM; struct sk_buff *ans_skb = NULL; void *data;
ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (ans_skb == NULL) return -ENOMEM;
data = genlmsg_put_reply(ans_skb, info, &netlbl_mgmt_gnl_family,
0, NLBL_MGMT_C_VERSION); if (data == NULL) goto version_failure;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.