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