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