18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * NetLabel CALIPSO/IPv6 Support 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * This file defines the CALIPSO/IPv6 functions for the NetLabel system. The 68c2ecf20Sopenharmony_ci * NetLabel system manages static and dynamic label mappings for network 78c2ecf20Sopenharmony_ci * protocols such as CIPSO and CALIPSO. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Authors: Paul Moore <paul@paul-moore.com> 108c2ecf20Sopenharmony_ci * Huw Davies <huw@codeweavers.com> 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* (c) Copyright Hewlett-Packard Development Company, L.P., 2006 148c2ecf20Sopenharmony_ci * (c) Copyright Huw Davies <huw@codeweavers.com>, 2015 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <linux/types.h> 188c2ecf20Sopenharmony_ci#include <linux/socket.h> 198c2ecf20Sopenharmony_ci#include <linux/string.h> 208c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 218c2ecf20Sopenharmony_ci#include <linux/audit.h> 228c2ecf20Sopenharmony_ci#include <linux/slab.h> 238c2ecf20Sopenharmony_ci#include <net/sock.h> 248c2ecf20Sopenharmony_ci#include <net/netlink.h> 258c2ecf20Sopenharmony_ci#include <net/genetlink.h> 268c2ecf20Sopenharmony_ci#include <net/netlabel.h> 278c2ecf20Sopenharmony_ci#include <net/calipso.h> 288c2ecf20Sopenharmony_ci#include <linux/atomic.h> 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#include "netlabel_user.h" 318c2ecf20Sopenharmony_ci#include "netlabel_calipso.h" 328c2ecf20Sopenharmony_ci#include "netlabel_mgmt.h" 338c2ecf20Sopenharmony_ci#include "netlabel_domainhash.h" 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/* Argument struct for calipso_doi_walk() */ 368c2ecf20Sopenharmony_cistruct netlbl_calipso_doiwalk_arg { 378c2ecf20Sopenharmony_ci struct netlink_callback *nl_cb; 388c2ecf20Sopenharmony_ci struct sk_buff *skb; 398c2ecf20Sopenharmony_ci u32 seq; 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* Argument struct for netlbl_domhsh_walk() */ 438c2ecf20Sopenharmony_cistruct netlbl_domhsh_walk_arg { 448c2ecf20Sopenharmony_ci struct netlbl_audit *audit_info; 458c2ecf20Sopenharmony_ci u32 doi; 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* NetLabel Generic NETLINK CALIPSO family */ 498c2ecf20Sopenharmony_cistatic struct genl_family netlbl_calipso_gnl_family; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/* NetLabel Netlink attribute policy */ 528c2ecf20Sopenharmony_cistatic const struct nla_policy calipso_genl_policy[NLBL_CALIPSO_A_MAX + 1] = { 538c2ecf20Sopenharmony_ci [NLBL_CALIPSO_A_DOI] = { .type = NLA_U32 }, 548c2ecf20Sopenharmony_ci [NLBL_CALIPSO_A_MTYPE] = { .type = NLA_U32 }, 558c2ecf20Sopenharmony_ci}; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic const struct netlbl_calipso_ops *calipso_ops; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci/** 608c2ecf20Sopenharmony_ci * netlbl_calipso_ops_register - Register the CALIPSO operations 618c2ecf20Sopenharmony_ci * @ops: ops to register 628c2ecf20Sopenharmony_ci * 638c2ecf20Sopenharmony_ci * Description: 648c2ecf20Sopenharmony_ci * Register the CALIPSO packet engine operations. 658c2ecf20Sopenharmony_ci * 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_ciconst struct netlbl_calipso_ops * 688c2ecf20Sopenharmony_cinetlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci return xchg(&calipso_ops, ops); 718c2ecf20Sopenharmony_ci} 728c2ecf20Sopenharmony_ciEXPORT_SYMBOL(netlbl_calipso_ops_register); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic const struct netlbl_calipso_ops *netlbl_calipso_ops_get(void) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci return READ_ONCE(calipso_ops); 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci/* NetLabel Command Handlers 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ci/** 828c2ecf20Sopenharmony_ci * netlbl_calipso_add_pass - Adds a CALIPSO pass DOI definition 838c2ecf20Sopenharmony_ci * @info: the Generic NETLINK info block 848c2ecf20Sopenharmony_ci * @audit_info: NetLabel audit information 858c2ecf20Sopenharmony_ci * 868c2ecf20Sopenharmony_ci * Description: 878c2ecf20Sopenharmony_ci * Create a new CALIPSO_MAP_PASS DOI definition based on the given ADD message 888c2ecf20Sopenharmony_ci * and add it to the CALIPSO engine. Return zero on success and non-zero on 898c2ecf20Sopenharmony_ci * error. 908c2ecf20Sopenharmony_ci * 918c2ecf20Sopenharmony_ci */ 928c2ecf20Sopenharmony_cistatic int netlbl_calipso_add_pass(struct genl_info *info, 938c2ecf20Sopenharmony_ci struct netlbl_audit *audit_info) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci int ret_val; 968c2ecf20Sopenharmony_ci struct calipso_doi *doi_def = NULL; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL); 998c2ecf20Sopenharmony_ci if (!doi_def) 1008c2ecf20Sopenharmony_ci return -ENOMEM; 1018c2ecf20Sopenharmony_ci doi_def->type = CALIPSO_MAP_PASS; 1028c2ecf20Sopenharmony_ci doi_def->doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]); 1038c2ecf20Sopenharmony_ci ret_val = calipso_doi_add(doi_def, audit_info); 1048c2ecf20Sopenharmony_ci if (ret_val != 0) 1058c2ecf20Sopenharmony_ci calipso_doi_free(doi_def); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci return ret_val; 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci/** 1118c2ecf20Sopenharmony_ci * netlbl_calipso_add - Handle an ADD message 1128c2ecf20Sopenharmony_ci * @skb: the NETLINK buffer 1138c2ecf20Sopenharmony_ci * @info: the Generic NETLINK info block 1148c2ecf20Sopenharmony_ci * 1158c2ecf20Sopenharmony_ci * Description: 1168c2ecf20Sopenharmony_ci * Create a new DOI definition based on the given ADD message and add it to the 1178c2ecf20Sopenharmony_ci * CALIPSO engine. Returns zero on success, negative values on failure. 1188c2ecf20Sopenharmony_ci * 1198c2ecf20Sopenharmony_ci */ 1208c2ecf20Sopenharmony_cistatic int netlbl_calipso_add(struct sk_buff *skb, struct genl_info *info) 1218c2ecf20Sopenharmony_ci{ 1228c2ecf20Sopenharmony_ci int ret_val = -EINVAL; 1238c2ecf20Sopenharmony_ci struct netlbl_audit audit_info; 1248c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci if (!info->attrs[NLBL_CALIPSO_A_DOI] || 1278c2ecf20Sopenharmony_ci !info->attrs[NLBL_CALIPSO_A_MTYPE]) 1288c2ecf20Sopenharmony_ci return -EINVAL; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci if (!ops) 1318c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci netlbl_netlink_auditinfo(&audit_info); 1348c2ecf20Sopenharmony_ci switch (nla_get_u32(info->attrs[NLBL_CALIPSO_A_MTYPE])) { 1358c2ecf20Sopenharmony_ci case CALIPSO_MAP_PASS: 1368c2ecf20Sopenharmony_ci ret_val = netlbl_calipso_add_pass(info, &audit_info); 1378c2ecf20Sopenharmony_ci break; 1388c2ecf20Sopenharmony_ci } 1398c2ecf20Sopenharmony_ci if (ret_val == 0) 1408c2ecf20Sopenharmony_ci atomic_inc(&netlabel_mgmt_protocount); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci return ret_val; 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci/** 1468c2ecf20Sopenharmony_ci * netlbl_calipso_list - Handle a LIST message 1478c2ecf20Sopenharmony_ci * @skb: the NETLINK buffer 1488c2ecf20Sopenharmony_ci * @info: the Generic NETLINK info block 1498c2ecf20Sopenharmony_ci * 1508c2ecf20Sopenharmony_ci * Description: 1518c2ecf20Sopenharmony_ci * Process a user generated LIST message and respond accordingly. 1528c2ecf20Sopenharmony_ci * Returns zero on success and negative values on error. 1538c2ecf20Sopenharmony_ci * 1548c2ecf20Sopenharmony_ci */ 1558c2ecf20Sopenharmony_cistatic int netlbl_calipso_list(struct sk_buff *skb, struct genl_info *info) 1568c2ecf20Sopenharmony_ci{ 1578c2ecf20Sopenharmony_ci int ret_val; 1588c2ecf20Sopenharmony_ci struct sk_buff *ans_skb = NULL; 1598c2ecf20Sopenharmony_ci void *data; 1608c2ecf20Sopenharmony_ci u32 doi; 1618c2ecf20Sopenharmony_ci struct calipso_doi *doi_def; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci if (!info->attrs[NLBL_CALIPSO_A_DOI]) { 1648c2ecf20Sopenharmony_ci ret_val = -EINVAL; 1658c2ecf20Sopenharmony_ci goto list_failure; 1668c2ecf20Sopenharmony_ci } 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]); 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci doi_def = calipso_doi_getdef(doi); 1718c2ecf20Sopenharmony_ci if (!doi_def) { 1728c2ecf20Sopenharmony_ci ret_val = -EINVAL; 1738c2ecf20Sopenharmony_ci goto list_failure; 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1778c2ecf20Sopenharmony_ci if (!ans_skb) { 1788c2ecf20Sopenharmony_ci ret_val = -ENOMEM; 1798c2ecf20Sopenharmony_ci goto list_failure_put; 1808c2ecf20Sopenharmony_ci } 1818c2ecf20Sopenharmony_ci data = genlmsg_put_reply(ans_skb, info, &netlbl_calipso_gnl_family, 1828c2ecf20Sopenharmony_ci 0, NLBL_CALIPSO_C_LIST); 1838c2ecf20Sopenharmony_ci if (!data) { 1848c2ecf20Sopenharmony_ci ret_val = -ENOMEM; 1858c2ecf20Sopenharmony_ci goto list_failure_put; 1868c2ecf20Sopenharmony_ci } 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci ret_val = nla_put_u32(ans_skb, NLBL_CALIPSO_A_MTYPE, doi_def->type); 1898c2ecf20Sopenharmony_ci if (ret_val != 0) 1908c2ecf20Sopenharmony_ci goto list_failure_put; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci calipso_doi_putdef(doi_def); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci genlmsg_end(ans_skb, data); 1958c2ecf20Sopenharmony_ci return genlmsg_reply(ans_skb, info); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_cilist_failure_put: 1988c2ecf20Sopenharmony_ci calipso_doi_putdef(doi_def); 1998c2ecf20Sopenharmony_cilist_failure: 2008c2ecf20Sopenharmony_ci kfree_skb(ans_skb); 2018c2ecf20Sopenharmony_ci return ret_val; 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci/** 2058c2ecf20Sopenharmony_ci * netlbl_calipso_listall_cb - calipso_doi_walk() callback for LISTALL 2068c2ecf20Sopenharmony_ci * @doi_def: the CALIPSO DOI definition 2078c2ecf20Sopenharmony_ci * @arg: the netlbl_calipso_doiwalk_arg structure 2088c2ecf20Sopenharmony_ci * 2098c2ecf20Sopenharmony_ci * Description: 2108c2ecf20Sopenharmony_ci * This function is designed to be used as a callback to the 2118c2ecf20Sopenharmony_ci * calipso_doi_walk() function for use in generating a response for a LISTALL 2128c2ecf20Sopenharmony_ci * message. Returns the size of the message on success, negative values on 2138c2ecf20Sopenharmony_ci * failure. 2148c2ecf20Sopenharmony_ci * 2158c2ecf20Sopenharmony_ci */ 2168c2ecf20Sopenharmony_cistatic int netlbl_calipso_listall_cb(struct calipso_doi *doi_def, void *arg) 2178c2ecf20Sopenharmony_ci{ 2188c2ecf20Sopenharmony_ci int ret_val = -ENOMEM; 2198c2ecf20Sopenharmony_ci struct netlbl_calipso_doiwalk_arg *cb_arg = arg; 2208c2ecf20Sopenharmony_ci void *data; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, 2238c2ecf20Sopenharmony_ci cb_arg->seq, &netlbl_calipso_gnl_family, 2248c2ecf20Sopenharmony_ci NLM_F_MULTI, NLBL_CALIPSO_C_LISTALL); 2258c2ecf20Sopenharmony_ci if (!data) 2268c2ecf20Sopenharmony_ci goto listall_cb_failure; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci ret_val = nla_put_u32(cb_arg->skb, NLBL_CALIPSO_A_DOI, doi_def->doi); 2298c2ecf20Sopenharmony_ci if (ret_val != 0) 2308c2ecf20Sopenharmony_ci goto listall_cb_failure; 2318c2ecf20Sopenharmony_ci ret_val = nla_put_u32(cb_arg->skb, 2328c2ecf20Sopenharmony_ci NLBL_CALIPSO_A_MTYPE, 2338c2ecf20Sopenharmony_ci doi_def->type); 2348c2ecf20Sopenharmony_ci if (ret_val != 0) 2358c2ecf20Sopenharmony_ci goto listall_cb_failure; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci genlmsg_end(cb_arg->skb, data); 2388c2ecf20Sopenharmony_ci return 0; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cilistall_cb_failure: 2418c2ecf20Sopenharmony_ci genlmsg_cancel(cb_arg->skb, data); 2428c2ecf20Sopenharmony_ci return ret_val; 2438c2ecf20Sopenharmony_ci} 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci/** 2468c2ecf20Sopenharmony_ci * netlbl_calipso_listall - Handle a LISTALL message 2478c2ecf20Sopenharmony_ci * @skb: the NETLINK buffer 2488c2ecf20Sopenharmony_ci * @cb: the NETLINK callback 2498c2ecf20Sopenharmony_ci * 2508c2ecf20Sopenharmony_ci * Description: 2518c2ecf20Sopenharmony_ci * Process a user generated LISTALL message and respond accordingly. Returns 2528c2ecf20Sopenharmony_ci * zero on success and negative values on error. 2538c2ecf20Sopenharmony_ci * 2548c2ecf20Sopenharmony_ci */ 2558c2ecf20Sopenharmony_cistatic int netlbl_calipso_listall(struct sk_buff *skb, 2568c2ecf20Sopenharmony_ci struct netlink_callback *cb) 2578c2ecf20Sopenharmony_ci{ 2588c2ecf20Sopenharmony_ci struct netlbl_calipso_doiwalk_arg cb_arg; 2598c2ecf20Sopenharmony_ci u32 doi_skip = cb->args[0]; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci cb_arg.nl_cb = cb; 2628c2ecf20Sopenharmony_ci cb_arg.skb = skb; 2638c2ecf20Sopenharmony_ci cb_arg.seq = cb->nlh->nlmsg_seq; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci calipso_doi_walk(&doi_skip, netlbl_calipso_listall_cb, &cb_arg); 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci cb->args[0] = doi_skip; 2688c2ecf20Sopenharmony_ci return skb->len; 2698c2ecf20Sopenharmony_ci} 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci/** 2728c2ecf20Sopenharmony_ci * netlbl_calipso_remove_cb - netlbl_calipso_remove() callback for REMOVE 2738c2ecf20Sopenharmony_ci * @entry: LSM domain mapping entry 2748c2ecf20Sopenharmony_ci * @arg: the netlbl_domhsh_walk_arg structure 2758c2ecf20Sopenharmony_ci * 2768c2ecf20Sopenharmony_ci * Description: 2778c2ecf20Sopenharmony_ci * This function is intended for use by netlbl_calipso_remove() as the callback 2788c2ecf20Sopenharmony_ci * for the netlbl_domhsh_walk() function; it removes LSM domain map entries 2798c2ecf20Sopenharmony_ci * which are associated with the CALIPSO DOI specified in @arg. Returns zero on 2808c2ecf20Sopenharmony_ci * success, negative values on failure. 2818c2ecf20Sopenharmony_ci * 2828c2ecf20Sopenharmony_ci */ 2838c2ecf20Sopenharmony_cistatic int netlbl_calipso_remove_cb(struct netlbl_dom_map *entry, void *arg) 2848c2ecf20Sopenharmony_ci{ 2858c2ecf20Sopenharmony_ci struct netlbl_domhsh_walk_arg *cb_arg = arg; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci if (entry->def.type == NETLBL_NLTYPE_CALIPSO && 2888c2ecf20Sopenharmony_ci entry->def.calipso->doi == cb_arg->doi) 2898c2ecf20Sopenharmony_ci return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info); 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci return 0; 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci/** 2958c2ecf20Sopenharmony_ci * netlbl_calipso_remove - Handle a REMOVE message 2968c2ecf20Sopenharmony_ci * @skb: the NETLINK buffer 2978c2ecf20Sopenharmony_ci * @info: the Generic NETLINK info block 2988c2ecf20Sopenharmony_ci * 2998c2ecf20Sopenharmony_ci * Description: 3008c2ecf20Sopenharmony_ci * Process a user generated REMOVE message and respond accordingly. Returns 3018c2ecf20Sopenharmony_ci * zero on success, negative values on failure. 3028c2ecf20Sopenharmony_ci * 3038c2ecf20Sopenharmony_ci */ 3048c2ecf20Sopenharmony_cistatic int netlbl_calipso_remove(struct sk_buff *skb, struct genl_info *info) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci int ret_val = -EINVAL; 3078c2ecf20Sopenharmony_ci struct netlbl_domhsh_walk_arg cb_arg; 3088c2ecf20Sopenharmony_ci struct netlbl_audit audit_info; 3098c2ecf20Sopenharmony_ci u32 skip_bkt = 0; 3108c2ecf20Sopenharmony_ci u32 skip_chain = 0; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci if (!info->attrs[NLBL_CALIPSO_A_DOI]) 3138c2ecf20Sopenharmony_ci return -EINVAL; 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci netlbl_netlink_auditinfo(&audit_info); 3168c2ecf20Sopenharmony_ci cb_arg.doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]); 3178c2ecf20Sopenharmony_ci cb_arg.audit_info = &audit_info; 3188c2ecf20Sopenharmony_ci ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain, 3198c2ecf20Sopenharmony_ci netlbl_calipso_remove_cb, &cb_arg); 3208c2ecf20Sopenharmony_ci if (ret_val == 0 || ret_val == -ENOENT) { 3218c2ecf20Sopenharmony_ci ret_val = calipso_doi_remove(cb_arg.doi, &audit_info); 3228c2ecf20Sopenharmony_ci if (ret_val == 0) 3238c2ecf20Sopenharmony_ci atomic_dec(&netlabel_mgmt_protocount); 3248c2ecf20Sopenharmony_ci } 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci return ret_val; 3278c2ecf20Sopenharmony_ci} 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci/* NetLabel Generic NETLINK Command Definitions 3308c2ecf20Sopenharmony_ci */ 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_cistatic const struct genl_small_ops netlbl_calipso_ops[] = { 3338c2ecf20Sopenharmony_ci { 3348c2ecf20Sopenharmony_ci .cmd = NLBL_CALIPSO_C_ADD, 3358c2ecf20Sopenharmony_ci .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 3368c2ecf20Sopenharmony_ci .flags = GENL_ADMIN_PERM, 3378c2ecf20Sopenharmony_ci .doit = netlbl_calipso_add, 3388c2ecf20Sopenharmony_ci .dumpit = NULL, 3398c2ecf20Sopenharmony_ci }, 3408c2ecf20Sopenharmony_ci { 3418c2ecf20Sopenharmony_ci .cmd = NLBL_CALIPSO_C_REMOVE, 3428c2ecf20Sopenharmony_ci .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 3438c2ecf20Sopenharmony_ci .flags = GENL_ADMIN_PERM, 3448c2ecf20Sopenharmony_ci .doit = netlbl_calipso_remove, 3458c2ecf20Sopenharmony_ci .dumpit = NULL, 3468c2ecf20Sopenharmony_ci }, 3478c2ecf20Sopenharmony_ci { 3488c2ecf20Sopenharmony_ci .cmd = NLBL_CALIPSO_C_LIST, 3498c2ecf20Sopenharmony_ci .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 3508c2ecf20Sopenharmony_ci .flags = 0, 3518c2ecf20Sopenharmony_ci .doit = netlbl_calipso_list, 3528c2ecf20Sopenharmony_ci .dumpit = NULL, 3538c2ecf20Sopenharmony_ci }, 3548c2ecf20Sopenharmony_ci { 3558c2ecf20Sopenharmony_ci .cmd = NLBL_CALIPSO_C_LISTALL, 3568c2ecf20Sopenharmony_ci .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 3578c2ecf20Sopenharmony_ci .flags = 0, 3588c2ecf20Sopenharmony_ci .doit = NULL, 3598c2ecf20Sopenharmony_ci .dumpit = netlbl_calipso_listall, 3608c2ecf20Sopenharmony_ci }, 3618c2ecf20Sopenharmony_ci}; 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_cistatic struct genl_family netlbl_calipso_gnl_family __ro_after_init = { 3648c2ecf20Sopenharmony_ci .hdrsize = 0, 3658c2ecf20Sopenharmony_ci .name = NETLBL_NLTYPE_CALIPSO_NAME, 3668c2ecf20Sopenharmony_ci .version = NETLBL_PROTO_VERSION, 3678c2ecf20Sopenharmony_ci .maxattr = NLBL_CALIPSO_A_MAX, 3688c2ecf20Sopenharmony_ci .policy = calipso_genl_policy, 3698c2ecf20Sopenharmony_ci .module = THIS_MODULE, 3708c2ecf20Sopenharmony_ci .small_ops = netlbl_calipso_ops, 3718c2ecf20Sopenharmony_ci .n_small_ops = ARRAY_SIZE(netlbl_calipso_ops), 3728c2ecf20Sopenharmony_ci}; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci/* NetLabel Generic NETLINK Protocol Functions 3758c2ecf20Sopenharmony_ci */ 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci/** 3788c2ecf20Sopenharmony_ci * netlbl_calipso_genl_init - Register the CALIPSO NetLabel component 3798c2ecf20Sopenharmony_ci * 3808c2ecf20Sopenharmony_ci * Description: 3818c2ecf20Sopenharmony_ci * Register the CALIPSO packet NetLabel component with the Generic NETLINK 3828c2ecf20Sopenharmony_ci * mechanism. Returns zero on success, negative values on failure. 3838c2ecf20Sopenharmony_ci * 3848c2ecf20Sopenharmony_ci */ 3858c2ecf20Sopenharmony_ciint __init netlbl_calipso_genl_init(void) 3868c2ecf20Sopenharmony_ci{ 3878c2ecf20Sopenharmony_ci return genl_register_family(&netlbl_calipso_gnl_family); 3888c2ecf20Sopenharmony_ci} 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci/** 3918c2ecf20Sopenharmony_ci * calipso_doi_add - Add a new DOI to the CALIPSO protocol engine 3928c2ecf20Sopenharmony_ci * @doi_def: the DOI structure 3938c2ecf20Sopenharmony_ci * @audit_info: NetLabel audit information 3948c2ecf20Sopenharmony_ci * 3958c2ecf20Sopenharmony_ci * Description: 3968c2ecf20Sopenharmony_ci * The caller defines a new DOI for use by the CALIPSO engine and calls this 3978c2ecf20Sopenharmony_ci * function to add it to the list of acceptable domains. The caller must 3988c2ecf20Sopenharmony_ci * ensure that the mapping table specified in @doi_def->map meets all of the 3998c2ecf20Sopenharmony_ci * requirements of the mapping type (see calipso.h for details). Returns 4008c2ecf20Sopenharmony_ci * zero on success and non-zero on failure. 4018c2ecf20Sopenharmony_ci * 4028c2ecf20Sopenharmony_ci */ 4038c2ecf20Sopenharmony_ciint calipso_doi_add(struct calipso_doi *doi_def, 4048c2ecf20Sopenharmony_ci struct netlbl_audit *audit_info) 4058c2ecf20Sopenharmony_ci{ 4068c2ecf20Sopenharmony_ci int ret_val = -ENOMSG; 4078c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci if (ops) 4108c2ecf20Sopenharmony_ci ret_val = ops->doi_add(doi_def, audit_info); 4118c2ecf20Sopenharmony_ci return ret_val; 4128c2ecf20Sopenharmony_ci} 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci/** 4158c2ecf20Sopenharmony_ci * calipso_doi_free - Frees a DOI definition 4168c2ecf20Sopenharmony_ci * @doi_def: the DOI definition 4178c2ecf20Sopenharmony_ci * 4188c2ecf20Sopenharmony_ci * Description: 4198c2ecf20Sopenharmony_ci * This function frees all of the memory associated with a DOI definition. 4208c2ecf20Sopenharmony_ci * 4218c2ecf20Sopenharmony_ci */ 4228c2ecf20Sopenharmony_civoid calipso_doi_free(struct calipso_doi *doi_def) 4238c2ecf20Sopenharmony_ci{ 4248c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci if (ops) 4278c2ecf20Sopenharmony_ci ops->doi_free(doi_def); 4288c2ecf20Sopenharmony_ci} 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci/** 4318c2ecf20Sopenharmony_ci * calipso_doi_remove - Remove an existing DOI from the CALIPSO protocol engine 4328c2ecf20Sopenharmony_ci * @doi: the DOI value 4338c2ecf20Sopenharmony_ci * @audit_info: NetLabel audit information 4348c2ecf20Sopenharmony_ci * 4358c2ecf20Sopenharmony_ci * Description: 4368c2ecf20Sopenharmony_ci * Removes a DOI definition from the CALIPSO engine. The NetLabel routines will 4378c2ecf20Sopenharmony_ci * be called to release their own LSM domain mappings as well as our own 4388c2ecf20Sopenharmony_ci * domain list. Returns zero on success and negative values on failure. 4398c2ecf20Sopenharmony_ci * 4408c2ecf20Sopenharmony_ci */ 4418c2ecf20Sopenharmony_ciint calipso_doi_remove(u32 doi, struct netlbl_audit *audit_info) 4428c2ecf20Sopenharmony_ci{ 4438c2ecf20Sopenharmony_ci int ret_val = -ENOMSG; 4448c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci if (ops) 4478c2ecf20Sopenharmony_ci ret_val = ops->doi_remove(doi, audit_info); 4488c2ecf20Sopenharmony_ci return ret_val; 4498c2ecf20Sopenharmony_ci} 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci/** 4528c2ecf20Sopenharmony_ci * calipso_doi_getdef - Returns a reference to a valid DOI definition 4538c2ecf20Sopenharmony_ci * @doi: the DOI value 4548c2ecf20Sopenharmony_ci * 4558c2ecf20Sopenharmony_ci * Description: 4568c2ecf20Sopenharmony_ci * Searches for a valid DOI definition and if one is found it is returned to 4578c2ecf20Sopenharmony_ci * the caller. Otherwise NULL is returned. The caller must ensure that 4588c2ecf20Sopenharmony_ci * calipso_doi_putdef() is called when the caller is done. 4598c2ecf20Sopenharmony_ci * 4608c2ecf20Sopenharmony_ci */ 4618c2ecf20Sopenharmony_cistruct calipso_doi *calipso_doi_getdef(u32 doi) 4628c2ecf20Sopenharmony_ci{ 4638c2ecf20Sopenharmony_ci struct calipso_doi *ret_val = NULL; 4648c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci if (ops) 4678c2ecf20Sopenharmony_ci ret_val = ops->doi_getdef(doi); 4688c2ecf20Sopenharmony_ci return ret_val; 4698c2ecf20Sopenharmony_ci} 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci/** 4728c2ecf20Sopenharmony_ci * calipso_doi_putdef - Releases a reference for the given DOI definition 4738c2ecf20Sopenharmony_ci * @doi_def: the DOI definition 4748c2ecf20Sopenharmony_ci * 4758c2ecf20Sopenharmony_ci * Description: 4768c2ecf20Sopenharmony_ci * Releases a DOI definition reference obtained from calipso_doi_getdef(). 4778c2ecf20Sopenharmony_ci * 4788c2ecf20Sopenharmony_ci */ 4798c2ecf20Sopenharmony_civoid calipso_doi_putdef(struct calipso_doi *doi_def) 4808c2ecf20Sopenharmony_ci{ 4818c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci if (ops) 4848c2ecf20Sopenharmony_ci ops->doi_putdef(doi_def); 4858c2ecf20Sopenharmony_ci} 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci/** 4888c2ecf20Sopenharmony_ci * calipso_doi_walk - Iterate through the DOI definitions 4898c2ecf20Sopenharmony_ci * @skip_cnt: skip past this number of DOI definitions, updated 4908c2ecf20Sopenharmony_ci * @callback: callback for each DOI definition 4918c2ecf20Sopenharmony_ci * @cb_arg: argument for the callback function 4928c2ecf20Sopenharmony_ci * 4938c2ecf20Sopenharmony_ci * Description: 4948c2ecf20Sopenharmony_ci * Iterate over the DOI definition list, skipping the first @skip_cnt entries. 4958c2ecf20Sopenharmony_ci * For each entry call @callback, if @callback returns a negative value stop 4968c2ecf20Sopenharmony_ci * 'walking' through the list and return. Updates the value in @skip_cnt upon 4978c2ecf20Sopenharmony_ci * return. Returns zero on success, negative values on failure. 4988c2ecf20Sopenharmony_ci * 4998c2ecf20Sopenharmony_ci */ 5008c2ecf20Sopenharmony_ciint calipso_doi_walk(u32 *skip_cnt, 5018c2ecf20Sopenharmony_ci int (*callback)(struct calipso_doi *doi_def, void *arg), 5028c2ecf20Sopenharmony_ci void *cb_arg) 5038c2ecf20Sopenharmony_ci{ 5048c2ecf20Sopenharmony_ci int ret_val = -ENOMSG; 5058c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci if (ops) 5088c2ecf20Sopenharmony_ci ret_val = ops->doi_walk(skip_cnt, callback, cb_arg); 5098c2ecf20Sopenharmony_ci return ret_val; 5108c2ecf20Sopenharmony_ci} 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci/** 5138c2ecf20Sopenharmony_ci * calipso_sock_getattr - Get the security attributes from a sock 5148c2ecf20Sopenharmony_ci * @sk: the sock 5158c2ecf20Sopenharmony_ci * @secattr: the security attributes 5168c2ecf20Sopenharmony_ci * 5178c2ecf20Sopenharmony_ci * Description: 5188c2ecf20Sopenharmony_ci * Query @sk to see if there is a CALIPSO option attached to the sock and if 5198c2ecf20Sopenharmony_ci * there is return the CALIPSO security attributes in @secattr. This function 5208c2ecf20Sopenharmony_ci * requires that @sk be locked, or privately held, but it does not do any 5218c2ecf20Sopenharmony_ci * locking itself. Returns zero on success and negative values on failure. 5228c2ecf20Sopenharmony_ci * 5238c2ecf20Sopenharmony_ci */ 5248c2ecf20Sopenharmony_ciint calipso_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) 5258c2ecf20Sopenharmony_ci{ 5268c2ecf20Sopenharmony_ci int ret_val = -ENOMSG; 5278c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci if (ops) 5308c2ecf20Sopenharmony_ci ret_val = ops->sock_getattr(sk, secattr); 5318c2ecf20Sopenharmony_ci return ret_val; 5328c2ecf20Sopenharmony_ci} 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci/** 5358c2ecf20Sopenharmony_ci * calipso_sock_setattr - Add a CALIPSO option to a socket 5368c2ecf20Sopenharmony_ci * @sk: the socket 5378c2ecf20Sopenharmony_ci * @doi_def: the CALIPSO DOI to use 5388c2ecf20Sopenharmony_ci * @secattr: the specific security attributes of the socket 5398c2ecf20Sopenharmony_ci * 5408c2ecf20Sopenharmony_ci * Description: 5418c2ecf20Sopenharmony_ci * Set the CALIPSO option on the given socket using the DOI definition and 5428c2ecf20Sopenharmony_ci * security attributes passed to the function. This function requires 5438c2ecf20Sopenharmony_ci * exclusive access to @sk, which means it either needs to be in the 5448c2ecf20Sopenharmony_ci * process of being created or locked. Returns zero on success and negative 5458c2ecf20Sopenharmony_ci * values on failure. 5468c2ecf20Sopenharmony_ci * 5478c2ecf20Sopenharmony_ci */ 5488c2ecf20Sopenharmony_ciint calipso_sock_setattr(struct sock *sk, 5498c2ecf20Sopenharmony_ci const struct calipso_doi *doi_def, 5508c2ecf20Sopenharmony_ci const struct netlbl_lsm_secattr *secattr) 5518c2ecf20Sopenharmony_ci{ 5528c2ecf20Sopenharmony_ci int ret_val = -ENOMSG; 5538c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci if (ops) 5568c2ecf20Sopenharmony_ci ret_val = ops->sock_setattr(sk, doi_def, secattr); 5578c2ecf20Sopenharmony_ci return ret_val; 5588c2ecf20Sopenharmony_ci} 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci/** 5618c2ecf20Sopenharmony_ci * calipso_sock_delattr - Delete the CALIPSO option from a socket 5628c2ecf20Sopenharmony_ci * @sk: the socket 5638c2ecf20Sopenharmony_ci * 5648c2ecf20Sopenharmony_ci * Description: 5658c2ecf20Sopenharmony_ci * Removes the CALIPSO option from a socket, if present. 5668c2ecf20Sopenharmony_ci * 5678c2ecf20Sopenharmony_ci */ 5688c2ecf20Sopenharmony_civoid calipso_sock_delattr(struct sock *sk) 5698c2ecf20Sopenharmony_ci{ 5708c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ci if (ops) 5738c2ecf20Sopenharmony_ci ops->sock_delattr(sk); 5748c2ecf20Sopenharmony_ci} 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci/** 5778c2ecf20Sopenharmony_ci * calipso_req_setattr - Add a CALIPSO option to a connection request socket 5788c2ecf20Sopenharmony_ci * @req: the connection request socket 5798c2ecf20Sopenharmony_ci * @doi_def: the CALIPSO DOI to use 5808c2ecf20Sopenharmony_ci * @secattr: the specific security attributes of the socket 5818c2ecf20Sopenharmony_ci * 5828c2ecf20Sopenharmony_ci * Description: 5838c2ecf20Sopenharmony_ci * Set the CALIPSO option on the given socket using the DOI definition and 5848c2ecf20Sopenharmony_ci * security attributes passed to the function. Returns zero on success and 5858c2ecf20Sopenharmony_ci * negative values on failure. 5868c2ecf20Sopenharmony_ci * 5878c2ecf20Sopenharmony_ci */ 5888c2ecf20Sopenharmony_ciint calipso_req_setattr(struct request_sock *req, 5898c2ecf20Sopenharmony_ci const struct calipso_doi *doi_def, 5908c2ecf20Sopenharmony_ci const struct netlbl_lsm_secattr *secattr) 5918c2ecf20Sopenharmony_ci{ 5928c2ecf20Sopenharmony_ci int ret_val = -ENOMSG; 5938c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci if (ops) 5968c2ecf20Sopenharmony_ci ret_val = ops->req_setattr(req, doi_def, secattr); 5978c2ecf20Sopenharmony_ci return ret_val; 5988c2ecf20Sopenharmony_ci} 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci/** 6018c2ecf20Sopenharmony_ci * calipso_req_delattr - Delete the CALIPSO option from a request socket 6028c2ecf20Sopenharmony_ci * @req: the request socket 6038c2ecf20Sopenharmony_ci * 6048c2ecf20Sopenharmony_ci * Description: 6058c2ecf20Sopenharmony_ci * Removes the CALIPSO option from a request socket, if present. 6068c2ecf20Sopenharmony_ci * 6078c2ecf20Sopenharmony_ci */ 6088c2ecf20Sopenharmony_civoid calipso_req_delattr(struct request_sock *req) 6098c2ecf20Sopenharmony_ci{ 6108c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_ci if (ops) 6138c2ecf20Sopenharmony_ci ops->req_delattr(req); 6148c2ecf20Sopenharmony_ci} 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci/** 6178c2ecf20Sopenharmony_ci * calipso_optptr - Find the CALIPSO option in the packet 6188c2ecf20Sopenharmony_ci * @skb: the packet 6198c2ecf20Sopenharmony_ci * 6208c2ecf20Sopenharmony_ci * Description: 6218c2ecf20Sopenharmony_ci * Parse the packet's IP header looking for a CALIPSO option. Returns a pointer 6228c2ecf20Sopenharmony_ci * to the start of the CALIPSO option on success, NULL if one if not found. 6238c2ecf20Sopenharmony_ci * 6248c2ecf20Sopenharmony_ci */ 6258c2ecf20Sopenharmony_ciunsigned char *calipso_optptr(const struct sk_buff *skb) 6268c2ecf20Sopenharmony_ci{ 6278c2ecf20Sopenharmony_ci unsigned char *ret_val = NULL; 6288c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci if (ops) 6318c2ecf20Sopenharmony_ci ret_val = ops->skbuff_optptr(skb); 6328c2ecf20Sopenharmony_ci return ret_val; 6338c2ecf20Sopenharmony_ci} 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci/** 6368c2ecf20Sopenharmony_ci * calipso_getattr - Get the security attributes from a memory block. 6378c2ecf20Sopenharmony_ci * @calipso: the CALIPSO option 6388c2ecf20Sopenharmony_ci * @secattr: the security attributes 6398c2ecf20Sopenharmony_ci * 6408c2ecf20Sopenharmony_ci * Description: 6418c2ecf20Sopenharmony_ci * Inspect @calipso and return the security attributes in @secattr. 6428c2ecf20Sopenharmony_ci * Returns zero on success and negative values on failure. 6438c2ecf20Sopenharmony_ci * 6448c2ecf20Sopenharmony_ci */ 6458c2ecf20Sopenharmony_ciint calipso_getattr(const unsigned char *calipso, 6468c2ecf20Sopenharmony_ci struct netlbl_lsm_secattr *secattr) 6478c2ecf20Sopenharmony_ci{ 6488c2ecf20Sopenharmony_ci int ret_val = -ENOMSG; 6498c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci if (ops) 6528c2ecf20Sopenharmony_ci ret_val = ops->opt_getattr(calipso, secattr); 6538c2ecf20Sopenharmony_ci return ret_val; 6548c2ecf20Sopenharmony_ci} 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci/** 6578c2ecf20Sopenharmony_ci * calipso_skbuff_setattr - Set the CALIPSO option on a packet 6588c2ecf20Sopenharmony_ci * @skb: the packet 6598c2ecf20Sopenharmony_ci * @doi_def: the CALIPSO DOI to use 6608c2ecf20Sopenharmony_ci * @secattr: the security attributes 6618c2ecf20Sopenharmony_ci * 6628c2ecf20Sopenharmony_ci * Description: 6638c2ecf20Sopenharmony_ci * Set the CALIPSO option on the given packet based on the security attributes. 6648c2ecf20Sopenharmony_ci * Returns a pointer to the IP header on success and NULL on failure. 6658c2ecf20Sopenharmony_ci * 6668c2ecf20Sopenharmony_ci */ 6678c2ecf20Sopenharmony_ciint calipso_skbuff_setattr(struct sk_buff *skb, 6688c2ecf20Sopenharmony_ci const struct calipso_doi *doi_def, 6698c2ecf20Sopenharmony_ci const struct netlbl_lsm_secattr *secattr) 6708c2ecf20Sopenharmony_ci{ 6718c2ecf20Sopenharmony_ci int ret_val = -ENOMSG; 6728c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci if (ops) 6758c2ecf20Sopenharmony_ci ret_val = ops->skbuff_setattr(skb, doi_def, secattr); 6768c2ecf20Sopenharmony_ci return ret_val; 6778c2ecf20Sopenharmony_ci} 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_ci/** 6808c2ecf20Sopenharmony_ci * calipso_skbuff_delattr - Delete any CALIPSO options from a packet 6818c2ecf20Sopenharmony_ci * @skb: the packet 6828c2ecf20Sopenharmony_ci * 6838c2ecf20Sopenharmony_ci * Description: 6848c2ecf20Sopenharmony_ci * Removes any and all CALIPSO options from the given packet. Returns zero on 6858c2ecf20Sopenharmony_ci * success, negative values on failure. 6868c2ecf20Sopenharmony_ci * 6878c2ecf20Sopenharmony_ci */ 6888c2ecf20Sopenharmony_ciint calipso_skbuff_delattr(struct sk_buff *skb) 6898c2ecf20Sopenharmony_ci{ 6908c2ecf20Sopenharmony_ci int ret_val = -ENOMSG; 6918c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci if (ops) 6948c2ecf20Sopenharmony_ci ret_val = ops->skbuff_delattr(skb); 6958c2ecf20Sopenharmony_ci return ret_val; 6968c2ecf20Sopenharmony_ci} 6978c2ecf20Sopenharmony_ci 6988c2ecf20Sopenharmony_ci/** 6998c2ecf20Sopenharmony_ci * calipso_cache_invalidate - Invalidates the current CALIPSO cache 7008c2ecf20Sopenharmony_ci * 7018c2ecf20Sopenharmony_ci * Description: 7028c2ecf20Sopenharmony_ci * Invalidates and frees any entries in the CALIPSO cache. Returns zero on 7038c2ecf20Sopenharmony_ci * success and negative values on failure. 7048c2ecf20Sopenharmony_ci * 7058c2ecf20Sopenharmony_ci */ 7068c2ecf20Sopenharmony_civoid calipso_cache_invalidate(void) 7078c2ecf20Sopenharmony_ci{ 7088c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 7098c2ecf20Sopenharmony_ci 7108c2ecf20Sopenharmony_ci if (ops) 7118c2ecf20Sopenharmony_ci ops->cache_invalidate(); 7128c2ecf20Sopenharmony_ci} 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci/** 7158c2ecf20Sopenharmony_ci * calipso_cache_add - Add an entry to the CALIPSO cache 7168c2ecf20Sopenharmony_ci * @calipso_ptr: the CALIPSO option 7178c2ecf20Sopenharmony_ci * @secattr: the packet's security attributes 7188c2ecf20Sopenharmony_ci * 7198c2ecf20Sopenharmony_ci * Description: 7208c2ecf20Sopenharmony_ci * Add a new entry into the CALIPSO label mapping cache. 7218c2ecf20Sopenharmony_ci * Returns zero on success, negative values on failure. 7228c2ecf20Sopenharmony_ci * 7238c2ecf20Sopenharmony_ci */ 7248c2ecf20Sopenharmony_ciint calipso_cache_add(const unsigned char *calipso_ptr, 7258c2ecf20Sopenharmony_ci const struct netlbl_lsm_secattr *secattr) 7268c2ecf20Sopenharmony_ci 7278c2ecf20Sopenharmony_ci{ 7288c2ecf20Sopenharmony_ci int ret_val = -ENOMSG; 7298c2ecf20Sopenharmony_ci const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_ci if (ops) 7328c2ecf20Sopenharmony_ci ret_val = ops->cache_add(calipso_ptr, secattr); 7338c2ecf20Sopenharmony_ci return ret_val; 7348c2ecf20Sopenharmony_ci} 735