cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

netlabel_calipso.c (19519B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * NetLabel CALIPSO/IPv6 Support
      4 *
      5 * This file defines the CALIPSO/IPv6 functions for the NetLabel system.  The
      6 * NetLabel system manages static and dynamic label mappings for network
      7 * protocols such as CIPSO and CALIPSO.
      8 *
      9 * Authors: Paul Moore <paul@paul-moore.com>
     10 *          Huw Davies <huw@codeweavers.com>
     11 */
     12
     13/* (c) Copyright Hewlett-Packard Development Company, L.P., 2006
     14 * (c) Copyright Huw Davies <huw@codeweavers.com>, 2015
     15 */
     16
     17#include <linux/types.h>
     18#include <linux/socket.h>
     19#include <linux/string.h>
     20#include <linux/skbuff.h>
     21#include <linux/audit.h>
     22#include <linux/slab.h>
     23#include <net/sock.h>
     24#include <net/netlink.h>
     25#include <net/genetlink.h>
     26#include <net/netlabel.h>
     27#include <net/calipso.h>
     28#include <linux/atomic.h>
     29
     30#include "netlabel_user.h"
     31#include "netlabel_calipso.h"
     32#include "netlabel_mgmt.h"
     33#include "netlabel_domainhash.h"
     34
     35/* Argument struct for calipso_doi_walk() */
     36struct netlbl_calipso_doiwalk_arg {
     37	struct netlink_callback *nl_cb;
     38	struct sk_buff *skb;
     39	u32 seq;
     40};
     41
     42/* Argument struct for netlbl_domhsh_walk() */
     43struct netlbl_domhsh_walk_arg {
     44	struct netlbl_audit *audit_info;
     45	u32 doi;
     46};
     47
     48/* NetLabel Generic NETLINK CALIPSO family */
     49static struct genl_family netlbl_calipso_gnl_family;
     50
     51/* NetLabel Netlink attribute policy */
     52static const struct nla_policy calipso_genl_policy[NLBL_CALIPSO_A_MAX + 1] = {
     53	[NLBL_CALIPSO_A_DOI] = { .type = NLA_U32 },
     54	[NLBL_CALIPSO_A_MTYPE] = { .type = NLA_U32 },
     55};
     56
     57/* NetLabel Command Handlers
     58 */
     59/**
     60 * netlbl_calipso_add_pass - Adds a CALIPSO pass DOI definition
     61 * @info: the Generic NETLINK info block
     62 * @audit_info: NetLabel audit information
     63 *
     64 * Description:
     65 * Create a new CALIPSO_MAP_PASS DOI definition based on the given ADD message
     66 * and add it to the CALIPSO engine.  Return zero on success and non-zero on
     67 * error.
     68 *
     69 */
     70static int netlbl_calipso_add_pass(struct genl_info *info,
     71				   struct netlbl_audit *audit_info)
     72{
     73	int ret_val;
     74	struct calipso_doi *doi_def = NULL;
     75
     76	doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
     77	if (!doi_def)
     78		return -ENOMEM;
     79	doi_def->type = CALIPSO_MAP_PASS;
     80	doi_def->doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]);
     81	ret_val = calipso_doi_add(doi_def, audit_info);
     82	if (ret_val != 0)
     83		calipso_doi_free(doi_def);
     84
     85	return ret_val;
     86}
     87
     88/**
     89 * netlbl_calipso_add - Handle an ADD message
     90 * @skb: the NETLINK buffer
     91 * @info: the Generic NETLINK info block
     92 *
     93 * Description:
     94 * Create a new DOI definition based on the given ADD message and add it to the
     95 * CALIPSO engine.  Returns zero on success, negative values on failure.
     96 *
     97 */
     98static int netlbl_calipso_add(struct sk_buff *skb, struct genl_info *info)
     99
    100{
    101	int ret_val = -EINVAL;
    102	struct netlbl_audit audit_info;
    103
    104	if (!info->attrs[NLBL_CALIPSO_A_DOI] ||
    105	    !info->attrs[NLBL_CALIPSO_A_MTYPE])
    106		return -EINVAL;
    107
    108	netlbl_netlink_auditinfo(&audit_info);
    109	switch (nla_get_u32(info->attrs[NLBL_CALIPSO_A_MTYPE])) {
    110	case CALIPSO_MAP_PASS:
    111		ret_val = netlbl_calipso_add_pass(info, &audit_info);
    112		break;
    113	}
    114	if (ret_val == 0)
    115		atomic_inc(&netlabel_mgmt_protocount);
    116
    117	return ret_val;
    118}
    119
    120/**
    121 * netlbl_calipso_list - Handle a LIST message
    122 * @skb: the NETLINK buffer
    123 * @info: the Generic NETLINK info block
    124 *
    125 * Description:
    126 * Process a user generated LIST message and respond accordingly.
    127 * Returns zero on success and negative values on error.
    128 *
    129 */
    130static int netlbl_calipso_list(struct sk_buff *skb, struct genl_info *info)
    131{
    132	int ret_val;
    133	struct sk_buff *ans_skb = NULL;
    134	void *data;
    135	u32 doi;
    136	struct calipso_doi *doi_def;
    137
    138	if (!info->attrs[NLBL_CALIPSO_A_DOI]) {
    139		ret_val = -EINVAL;
    140		goto list_failure;
    141	}
    142
    143	doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]);
    144
    145	doi_def = calipso_doi_getdef(doi);
    146	if (!doi_def) {
    147		ret_val = -EINVAL;
    148		goto list_failure;
    149	}
    150
    151	ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
    152	if (!ans_skb) {
    153		ret_val = -ENOMEM;
    154		goto list_failure_put;
    155	}
    156	data = genlmsg_put_reply(ans_skb, info, &netlbl_calipso_gnl_family,
    157				 0, NLBL_CALIPSO_C_LIST);
    158	if (!data) {
    159		ret_val = -ENOMEM;
    160		goto list_failure_put;
    161	}
    162
    163	ret_val = nla_put_u32(ans_skb, NLBL_CALIPSO_A_MTYPE, doi_def->type);
    164	if (ret_val != 0)
    165		goto list_failure_put;
    166
    167	calipso_doi_putdef(doi_def);
    168
    169	genlmsg_end(ans_skb, data);
    170	return genlmsg_reply(ans_skb, info);
    171
    172list_failure_put:
    173	calipso_doi_putdef(doi_def);
    174list_failure:
    175	kfree_skb(ans_skb);
    176	return ret_val;
    177}
    178
    179/**
    180 * netlbl_calipso_listall_cb - calipso_doi_walk() callback for LISTALL
    181 * @doi_def: the CALIPSO DOI definition
    182 * @arg: the netlbl_calipso_doiwalk_arg structure
    183 *
    184 * Description:
    185 * This function is designed to be used as a callback to the
    186 * calipso_doi_walk() function for use in generating a response for a LISTALL
    187 * message.  Returns the size of the message on success, negative values on
    188 * failure.
    189 *
    190 */
    191static int netlbl_calipso_listall_cb(struct calipso_doi *doi_def, void *arg)
    192{
    193	int ret_val = -ENOMEM;
    194	struct netlbl_calipso_doiwalk_arg *cb_arg = arg;
    195	void *data;
    196
    197	data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
    198			   cb_arg->seq, &netlbl_calipso_gnl_family,
    199			   NLM_F_MULTI, NLBL_CALIPSO_C_LISTALL);
    200	if (!data)
    201		goto listall_cb_failure;
    202
    203	ret_val = nla_put_u32(cb_arg->skb, NLBL_CALIPSO_A_DOI, doi_def->doi);
    204	if (ret_val != 0)
    205		goto listall_cb_failure;
    206	ret_val = nla_put_u32(cb_arg->skb,
    207			      NLBL_CALIPSO_A_MTYPE,
    208			      doi_def->type);
    209	if (ret_val != 0)
    210		goto listall_cb_failure;
    211
    212	genlmsg_end(cb_arg->skb, data);
    213	return 0;
    214
    215listall_cb_failure:
    216	genlmsg_cancel(cb_arg->skb, data);
    217	return ret_val;
    218}
    219
    220/**
    221 * netlbl_calipso_listall - Handle a LISTALL message
    222 * @skb: the NETLINK buffer
    223 * @cb: the NETLINK callback
    224 *
    225 * Description:
    226 * Process a user generated LISTALL message and respond accordingly.  Returns
    227 * zero on success and negative values on error.
    228 *
    229 */
    230static int netlbl_calipso_listall(struct sk_buff *skb,
    231				  struct netlink_callback *cb)
    232{
    233	struct netlbl_calipso_doiwalk_arg cb_arg;
    234	u32 doi_skip = cb->args[0];
    235
    236	cb_arg.nl_cb = cb;
    237	cb_arg.skb = skb;
    238	cb_arg.seq = cb->nlh->nlmsg_seq;
    239
    240	calipso_doi_walk(&doi_skip, netlbl_calipso_listall_cb, &cb_arg);
    241
    242	cb->args[0] = doi_skip;
    243	return skb->len;
    244}
    245
    246/**
    247 * netlbl_calipso_remove_cb - netlbl_calipso_remove() callback for REMOVE
    248 * @entry: LSM domain mapping entry
    249 * @arg: the netlbl_domhsh_walk_arg structure
    250 *
    251 * Description:
    252 * This function is intended for use by netlbl_calipso_remove() as the callback
    253 * for the netlbl_domhsh_walk() function; it removes LSM domain map entries
    254 * which are associated with the CALIPSO DOI specified in @arg.  Returns zero on
    255 * success, negative values on failure.
    256 *
    257 */
    258static int netlbl_calipso_remove_cb(struct netlbl_dom_map *entry, void *arg)
    259{
    260	struct netlbl_domhsh_walk_arg *cb_arg = arg;
    261
    262	if (entry->def.type == NETLBL_NLTYPE_CALIPSO &&
    263	    entry->def.calipso->doi == cb_arg->doi)
    264		return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info);
    265
    266	return 0;
    267}
    268
    269/**
    270 * netlbl_calipso_remove - Handle a REMOVE message
    271 * @skb: the NETLINK buffer
    272 * @info: the Generic NETLINK info block
    273 *
    274 * Description:
    275 * Process a user generated REMOVE message and respond accordingly.  Returns
    276 * zero on success, negative values on failure.
    277 *
    278 */
    279static int netlbl_calipso_remove(struct sk_buff *skb, struct genl_info *info)
    280{
    281	int ret_val = -EINVAL;
    282	struct netlbl_domhsh_walk_arg cb_arg;
    283	struct netlbl_audit audit_info;
    284	u32 skip_bkt = 0;
    285	u32 skip_chain = 0;
    286
    287	if (!info->attrs[NLBL_CALIPSO_A_DOI])
    288		return -EINVAL;
    289
    290	netlbl_netlink_auditinfo(&audit_info);
    291	cb_arg.doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]);
    292	cb_arg.audit_info = &audit_info;
    293	ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
    294				     netlbl_calipso_remove_cb, &cb_arg);
    295	if (ret_val == 0 || ret_val == -ENOENT) {
    296		ret_val = calipso_doi_remove(cb_arg.doi, &audit_info);
    297		if (ret_val == 0)
    298			atomic_dec(&netlabel_mgmt_protocount);
    299	}
    300
    301	return ret_val;
    302}
    303
    304/* NetLabel Generic NETLINK Command Definitions
    305 */
    306
    307static const struct genl_small_ops netlbl_calipso_ops[] = {
    308	{
    309	.cmd = NLBL_CALIPSO_C_ADD,
    310	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
    311	.flags = GENL_ADMIN_PERM,
    312	.doit = netlbl_calipso_add,
    313	.dumpit = NULL,
    314	},
    315	{
    316	.cmd = NLBL_CALIPSO_C_REMOVE,
    317	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
    318	.flags = GENL_ADMIN_PERM,
    319	.doit = netlbl_calipso_remove,
    320	.dumpit = NULL,
    321	},
    322	{
    323	.cmd = NLBL_CALIPSO_C_LIST,
    324	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
    325	.flags = 0,
    326	.doit = netlbl_calipso_list,
    327	.dumpit = NULL,
    328	},
    329	{
    330	.cmd = NLBL_CALIPSO_C_LISTALL,
    331	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
    332	.flags = 0,
    333	.doit = NULL,
    334	.dumpit = netlbl_calipso_listall,
    335	},
    336};
    337
    338static struct genl_family netlbl_calipso_gnl_family __ro_after_init = {
    339	.hdrsize = 0,
    340	.name = NETLBL_NLTYPE_CALIPSO_NAME,
    341	.version = NETLBL_PROTO_VERSION,
    342	.maxattr = NLBL_CALIPSO_A_MAX,
    343	.policy = calipso_genl_policy,
    344	.module = THIS_MODULE,
    345	.small_ops = netlbl_calipso_ops,
    346	.n_small_ops = ARRAY_SIZE(netlbl_calipso_ops),
    347};
    348
    349/* NetLabel Generic NETLINK Protocol Functions
    350 */
    351
    352/**
    353 * netlbl_calipso_genl_init - Register the CALIPSO NetLabel component
    354 *
    355 * Description:
    356 * Register the CALIPSO packet NetLabel component with the Generic NETLINK
    357 * mechanism.  Returns zero on success, negative values on failure.
    358 *
    359 */
    360int __init netlbl_calipso_genl_init(void)
    361{
    362	return genl_register_family(&netlbl_calipso_gnl_family);
    363}
    364
    365static const struct netlbl_calipso_ops *calipso_ops;
    366
    367/**
    368 * netlbl_calipso_ops_register - Register the CALIPSO operations
    369 * @ops: ops to register
    370 *
    371 * Description:
    372 * Register the CALIPSO packet engine operations.
    373 *
    374 */
    375const struct netlbl_calipso_ops *
    376netlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops)
    377{
    378	return xchg(&calipso_ops, ops);
    379}
    380EXPORT_SYMBOL(netlbl_calipso_ops_register);
    381
    382static const struct netlbl_calipso_ops *netlbl_calipso_ops_get(void)
    383{
    384	return READ_ONCE(calipso_ops);
    385}
    386
    387/**
    388 * calipso_doi_add - Add a new DOI to the CALIPSO protocol engine
    389 * @doi_def: the DOI structure
    390 * @audit_info: NetLabel audit information
    391 *
    392 * Description:
    393 * The caller defines a new DOI for use by the CALIPSO engine and calls this
    394 * function to add it to the list of acceptable domains.  The caller must
    395 * ensure that the mapping table specified in @doi_def->map meets all of the
    396 * requirements of the mapping type (see calipso.h for details).  Returns
    397 * zero on success and non-zero on failure.
    398 *
    399 */
    400int calipso_doi_add(struct calipso_doi *doi_def,
    401		    struct netlbl_audit *audit_info)
    402{
    403	int ret_val = -ENOMSG;
    404	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    405
    406	if (ops)
    407		ret_val = ops->doi_add(doi_def, audit_info);
    408	return ret_val;
    409}
    410
    411/**
    412 * calipso_doi_free - Frees a DOI definition
    413 * @doi_def: the DOI definition
    414 *
    415 * Description:
    416 * This function frees all of the memory associated with a DOI definition.
    417 *
    418 */
    419void calipso_doi_free(struct calipso_doi *doi_def)
    420{
    421	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    422
    423	if (ops)
    424		ops->doi_free(doi_def);
    425}
    426
    427/**
    428 * calipso_doi_remove - Remove an existing DOI from the CALIPSO protocol engine
    429 * @doi: the DOI value
    430 * @audit_info: NetLabel audit information
    431 *
    432 * Description:
    433 * Removes a DOI definition from the CALIPSO engine.  The NetLabel routines will
    434 * be called to release their own LSM domain mappings as well as our own
    435 * domain list.  Returns zero on success and negative values on failure.
    436 *
    437 */
    438int calipso_doi_remove(u32 doi, struct netlbl_audit *audit_info)
    439{
    440	int ret_val = -ENOMSG;
    441	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    442
    443	if (ops)
    444		ret_val = ops->doi_remove(doi, audit_info);
    445	return ret_val;
    446}
    447
    448/**
    449 * calipso_doi_getdef - Returns a reference to a valid DOI definition
    450 * @doi: the DOI value
    451 *
    452 * Description:
    453 * Searches for a valid DOI definition and if one is found it is returned to
    454 * the caller.  Otherwise NULL is returned.  The caller must ensure that
    455 * calipso_doi_putdef() is called when the caller is done.
    456 *
    457 */
    458struct calipso_doi *calipso_doi_getdef(u32 doi)
    459{
    460	struct calipso_doi *ret_val = NULL;
    461	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    462
    463	if (ops)
    464		ret_val = ops->doi_getdef(doi);
    465	return ret_val;
    466}
    467
    468/**
    469 * calipso_doi_putdef - Releases a reference for the given DOI definition
    470 * @doi_def: the DOI definition
    471 *
    472 * Description:
    473 * Releases a DOI definition reference obtained from calipso_doi_getdef().
    474 *
    475 */
    476void calipso_doi_putdef(struct calipso_doi *doi_def)
    477{
    478	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    479
    480	if (ops)
    481		ops->doi_putdef(doi_def);
    482}
    483
    484/**
    485 * calipso_doi_walk - Iterate through the DOI definitions
    486 * @skip_cnt: skip past this number of DOI definitions, updated
    487 * @callback: callback for each DOI definition
    488 * @cb_arg: argument for the callback function
    489 *
    490 * Description:
    491 * Iterate over the DOI definition list, skipping the first @skip_cnt entries.
    492 * For each entry call @callback, if @callback returns a negative value stop
    493 * 'walking' through the list and return.  Updates the value in @skip_cnt upon
    494 * return.  Returns zero on success, negative values on failure.
    495 *
    496 */
    497int calipso_doi_walk(u32 *skip_cnt,
    498		     int (*callback)(struct calipso_doi *doi_def, void *arg),
    499		     void *cb_arg)
    500{
    501	int ret_val = -ENOMSG;
    502	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    503
    504	if (ops)
    505		ret_val = ops->doi_walk(skip_cnt, callback, cb_arg);
    506	return ret_val;
    507}
    508
    509/**
    510 * calipso_sock_getattr - Get the security attributes from a sock
    511 * @sk: the sock
    512 * @secattr: the security attributes
    513 *
    514 * Description:
    515 * Query @sk to see if there is a CALIPSO option attached to the sock and if
    516 * there is return the CALIPSO security attributes in @secattr.  This function
    517 * requires that @sk be locked, or privately held, but it does not do any
    518 * locking itself.  Returns zero on success and negative values on failure.
    519 *
    520 */
    521int calipso_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
    522{
    523	int ret_val = -ENOMSG;
    524	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    525
    526	if (ops)
    527		ret_val = ops->sock_getattr(sk, secattr);
    528	return ret_val;
    529}
    530
    531/**
    532 * calipso_sock_setattr - Add a CALIPSO option to a socket
    533 * @sk: the socket
    534 * @doi_def: the CALIPSO DOI to use
    535 * @secattr: the specific security attributes of the socket
    536 *
    537 * Description:
    538 * Set the CALIPSO option on the given socket using the DOI definition and
    539 * security attributes passed to the function.  This function requires
    540 * exclusive access to @sk, which means it either needs to be in the
    541 * process of being created or locked.  Returns zero on success and negative
    542 * values on failure.
    543 *
    544 */
    545int calipso_sock_setattr(struct sock *sk,
    546			 const struct calipso_doi *doi_def,
    547			 const struct netlbl_lsm_secattr *secattr)
    548{
    549	int ret_val = -ENOMSG;
    550	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    551
    552	if (ops)
    553		ret_val = ops->sock_setattr(sk, doi_def, secattr);
    554	return ret_val;
    555}
    556
    557/**
    558 * calipso_sock_delattr - Delete the CALIPSO option from a socket
    559 * @sk: the socket
    560 *
    561 * Description:
    562 * Removes the CALIPSO option from a socket, if present.
    563 *
    564 */
    565void calipso_sock_delattr(struct sock *sk)
    566{
    567	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    568
    569	if (ops)
    570		ops->sock_delattr(sk);
    571}
    572
    573/**
    574 * calipso_req_setattr - Add a CALIPSO option to a connection request socket
    575 * @req: the connection request socket
    576 * @doi_def: the CALIPSO DOI to use
    577 * @secattr: the specific security attributes of the socket
    578 *
    579 * Description:
    580 * Set the CALIPSO option on the given socket using the DOI definition and
    581 * security attributes passed to the function.  Returns zero on success and
    582 * negative values on failure.
    583 *
    584 */
    585int calipso_req_setattr(struct request_sock *req,
    586			const struct calipso_doi *doi_def,
    587			const struct netlbl_lsm_secattr *secattr)
    588{
    589	int ret_val = -ENOMSG;
    590	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    591
    592	if (ops)
    593		ret_val = ops->req_setattr(req, doi_def, secattr);
    594	return ret_val;
    595}
    596
    597/**
    598 * calipso_req_delattr - Delete the CALIPSO option from a request socket
    599 * @req: the request socket
    600 *
    601 * Description:
    602 * Removes the CALIPSO option from a request socket, if present.
    603 *
    604 */
    605void calipso_req_delattr(struct request_sock *req)
    606{
    607	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    608
    609	if (ops)
    610		ops->req_delattr(req);
    611}
    612
    613/**
    614 * calipso_optptr - Find the CALIPSO option in the packet
    615 * @skb: the packet
    616 *
    617 * Description:
    618 * Parse the packet's IP header looking for a CALIPSO option.  Returns a pointer
    619 * to the start of the CALIPSO option on success, NULL if one if not found.
    620 *
    621 */
    622unsigned char *calipso_optptr(const struct sk_buff *skb)
    623{
    624	unsigned char *ret_val = NULL;
    625	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    626
    627	if (ops)
    628		ret_val = ops->skbuff_optptr(skb);
    629	return ret_val;
    630}
    631
    632/**
    633 * calipso_getattr - Get the security attributes from a memory block.
    634 * @calipso: the CALIPSO option
    635 * @secattr: the security attributes
    636 *
    637 * Description:
    638 * Inspect @calipso and return the security attributes in @secattr.
    639 * Returns zero on success and negative values on failure.
    640 *
    641 */
    642int calipso_getattr(const unsigned char *calipso,
    643		    struct netlbl_lsm_secattr *secattr)
    644{
    645	int ret_val = -ENOMSG;
    646	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    647
    648	if (ops)
    649		ret_val = ops->opt_getattr(calipso, secattr);
    650	return ret_val;
    651}
    652
    653/**
    654 * calipso_skbuff_setattr - Set the CALIPSO option on a packet
    655 * @skb: the packet
    656 * @doi_def: the CALIPSO DOI to use
    657 * @secattr: the security attributes
    658 *
    659 * Description:
    660 * Set the CALIPSO option on the given packet based on the security attributes.
    661 * Returns a pointer to the IP header on success and NULL on failure.
    662 *
    663 */
    664int calipso_skbuff_setattr(struct sk_buff *skb,
    665			   const struct calipso_doi *doi_def,
    666			   const struct netlbl_lsm_secattr *secattr)
    667{
    668	int ret_val = -ENOMSG;
    669	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    670
    671	if (ops)
    672		ret_val = ops->skbuff_setattr(skb, doi_def, secattr);
    673	return ret_val;
    674}
    675
    676/**
    677 * calipso_skbuff_delattr - Delete any CALIPSO options from a packet
    678 * @skb: the packet
    679 *
    680 * Description:
    681 * Removes any and all CALIPSO options from the given packet.  Returns zero on
    682 * success, negative values on failure.
    683 *
    684 */
    685int calipso_skbuff_delattr(struct sk_buff *skb)
    686{
    687	int ret_val = -ENOMSG;
    688	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    689
    690	if (ops)
    691		ret_val = ops->skbuff_delattr(skb);
    692	return ret_val;
    693}
    694
    695/**
    696 * calipso_cache_invalidate - Invalidates the current CALIPSO cache
    697 *
    698 * Description:
    699 * Invalidates and frees any entries in the CALIPSO cache.  Returns zero on
    700 * success and negative values on failure.
    701 *
    702 */
    703void calipso_cache_invalidate(void)
    704{
    705	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    706
    707	if (ops)
    708		ops->cache_invalidate();
    709}
    710
    711/**
    712 * calipso_cache_add - Add an entry to the CALIPSO cache
    713 * @calipso_ptr: the CALIPSO option
    714 * @secattr: the packet's security attributes
    715 *
    716 * Description:
    717 * Add a new entry into the CALIPSO label mapping cache.
    718 * Returns zero on success, negative values on failure.
    719 *
    720 */
    721int calipso_cache_add(const unsigned char *calipso_ptr,
    722		      const struct netlbl_lsm_secattr *secattr)
    723
    724{
    725	int ret_val = -ENOMSG;
    726	const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
    727
    728	if (ops)
    729		ret_val = ops->cache_add(calipso_ptr, secattr);
    730	return ret_val;
    731}