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 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 325 .flags = GENL_ADMIN_PERM, 326 .doit = netlbl_calipso_add, 327 .dumpit = NULL, 328 }, 329 { 330 .cmd = NLBL_CALIPSO_C_REMOVE, 331 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 332 .flags = GENL_ADMIN_PERM, 333 .doit = netlbl_calipso_remove, 334 .dumpit = NULL, 335 }, 336 { 337 .cmd = NLBL_CALIPSO_C_LIST, 338 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 339 .flags = 0, 340 .doit = netlbl_calipso_list, 341 .dumpit = NULL, 342 }, 343 { 344 .cmd = NLBL_CALIPSO_C_LISTALL, 345 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 346 .flags = 0, 347 .doit = NULL, 348 .dumpit = netlbl_calipso_listall, 349 }, 350 }; 351 352 static struct genl_family netlbl_calipso_gnl_family __ro_after_init = { 353 .hdrsize = 0, 354 .name = NETLBL_NLTYPE_CALIPSO_NAME, 355 .version = NETLBL_PROTO_VERSION, 356 .maxattr = NLBL_CALIPSO_A_MAX, 357 .policy = calipso_genl_policy, 358 .module = THIS_MODULE, 359 .ops = netlbl_calipso_ops, 360 .n_ops = ARRAY_SIZE(netlbl_calipso_ops), 361 }; 362 363 /* NetLabel Generic NETLINK Protocol Functions 364 */ 365 366 /** 367 * netlbl_calipso_genl_init - Register the CALIPSO NetLabel component 368 * 369 * Description: 370 * Register the CALIPSO packet NetLabel component with the Generic NETLINK 371 * mechanism. Returns zero on success, negative values on failure. 372 * 373 */ 374 int __init netlbl_calipso_genl_init(void) 375 { 376 return genl_register_family(&netlbl_calipso_gnl_family); 377 } 378 379 static const struct netlbl_calipso_ops *calipso_ops; 380 381 /** 382 * netlbl_calipso_ops_register - Register the CALIPSO operations 383 * 384 * Description: 385 * Register the CALIPSO packet engine operations. 386 * 387 */ 388 const struct netlbl_calipso_ops * 389 netlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops) 390 { 391 return xchg(&calipso_ops, ops); 392 } 393 EXPORT_SYMBOL(netlbl_calipso_ops_register); 394 395 static const struct netlbl_calipso_ops *netlbl_calipso_ops_get(void) 396 { 397 return READ_ONCE(calipso_ops); 398 } 399 400 /** 401 * calipso_doi_add - Add a new DOI to the CALIPSO protocol engine 402 * @doi_def: the DOI structure 403 * @audit_info: NetLabel audit information 404 * 405 * Description: 406 * The caller defines a new DOI for use by the CALIPSO engine and calls this 407 * function to add it to the list of acceptable domains. The caller must 408 * ensure that the mapping table specified in @doi_def->map meets all of the 409 * requirements of the mapping type (see calipso.h for details). Returns 410 * zero on success and non-zero on failure. 411 * 412 */ 413 int calipso_doi_add(struct calipso_doi *doi_def, 414 struct netlbl_audit *audit_info) 415 { 416 int ret_val = -ENOMSG; 417 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 418 419 if (ops) 420 ret_val = ops->doi_add(doi_def, audit_info); 421 return ret_val; 422 } 423 424 /** 425 * calipso_doi_free - Frees a DOI definition 426 * @doi_def: the DOI definition 427 * 428 * Description: 429 * This function frees all of the memory associated with a DOI definition. 430 * 431 */ 432 void calipso_doi_free(struct calipso_doi *doi_def) 433 { 434 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 435 436 if (ops) 437 ops->doi_free(doi_def); 438 } 439 440 /** 441 * calipso_doi_remove - Remove an existing DOI from the CALIPSO protocol engine 442 * @doi: the DOI value 443 * @audit_secid: the LSM secid to use in the audit message 444 * 445 * Description: 446 * Removes a DOI definition from the CALIPSO engine. The NetLabel routines will 447 * be called to release their own LSM domain mappings as well as our own 448 * domain list. Returns zero on success and negative values on failure. 449 * 450 */ 451 int calipso_doi_remove(u32 doi, struct netlbl_audit *audit_info) 452 { 453 int ret_val = -ENOMSG; 454 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 455 456 if (ops) 457 ret_val = ops->doi_remove(doi, audit_info); 458 return ret_val; 459 } 460 461 /** 462 * calipso_doi_getdef - Returns a reference to a valid DOI definition 463 * @doi: the DOI value 464 * 465 * Description: 466 * Searches for a valid DOI definition and if one is found it is returned to 467 * the caller. Otherwise NULL is returned. The caller must ensure that 468 * calipso_doi_putdef() is called when the caller is done. 469 * 470 */ 471 struct calipso_doi *calipso_doi_getdef(u32 doi) 472 { 473 struct calipso_doi *ret_val = NULL; 474 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 475 476 if (ops) 477 ret_val = ops->doi_getdef(doi); 478 return ret_val; 479 } 480 481 /** 482 * calipso_doi_putdef - Releases a reference for the given DOI definition 483 * @doi_def: the DOI definition 484 * 485 * Description: 486 * Releases a DOI definition reference obtained from calipso_doi_getdef(). 487 * 488 */ 489 void calipso_doi_putdef(struct calipso_doi *doi_def) 490 { 491 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 492 493 if (ops) 494 ops->doi_putdef(doi_def); 495 } 496 497 /** 498 * calipso_doi_walk - Iterate through the DOI definitions 499 * @skip_cnt: skip past this number of DOI definitions, updated 500 * @callback: callback for each DOI definition 501 * @cb_arg: argument for the callback function 502 * 503 * Description: 504 * Iterate over the DOI definition list, skipping the first @skip_cnt entries. 505 * For each entry call @callback, if @callback returns a negative value stop 506 * 'walking' through the list and return. Updates the value in @skip_cnt upon 507 * return. Returns zero on success, negative values on failure. 508 * 509 */ 510 int calipso_doi_walk(u32 *skip_cnt, 511 int (*callback)(struct calipso_doi *doi_def, void *arg), 512 void *cb_arg) 513 { 514 int ret_val = -ENOMSG; 515 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 516 517 if (ops) 518 ret_val = ops->doi_walk(skip_cnt, callback, cb_arg); 519 return ret_val; 520 } 521 522 /** 523 * calipso_sock_getattr - Get the security attributes from a sock 524 * @sk: the sock 525 * @secattr: the security attributes 526 * 527 * Description: 528 * Query @sk to see if there is a CALIPSO option attached to the sock and if 529 * there is return the CALIPSO security attributes in @secattr. This function 530 * requires that @sk be locked, or privately held, but it does not do any 531 * locking itself. Returns zero on success and negative values on failure. 532 * 533 */ 534 int calipso_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) 535 { 536 int ret_val = -ENOMSG; 537 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 538 539 if (ops) 540 ret_val = ops->sock_getattr(sk, secattr); 541 return ret_val; 542 } 543 544 /** 545 * calipso_sock_setattr - Add a CALIPSO option to a socket 546 * @sk: the socket 547 * @doi_def: the CALIPSO DOI to use 548 * @secattr: the specific security attributes of the socket 549 * 550 * Description: 551 * Set the CALIPSO option on the given socket using the DOI definition and 552 * security attributes passed to the function. This function requires 553 * exclusive access to @sk, which means it either needs to be in the 554 * process of being created or locked. Returns zero on success and negative 555 * values on failure. 556 * 557 */ 558 int calipso_sock_setattr(struct sock *sk, 559 const struct calipso_doi *doi_def, 560 const struct netlbl_lsm_secattr *secattr) 561 { 562 int ret_val = -ENOMSG; 563 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 564 565 if (ops) 566 ret_val = ops->sock_setattr(sk, doi_def, secattr); 567 return ret_val; 568 } 569 570 /** 571 * calipso_sock_delattr - Delete the CALIPSO option from a socket 572 * @sk: the socket 573 * 574 * Description: 575 * Removes the CALIPSO option from a socket, if present. 576 * 577 */ 578 void calipso_sock_delattr(struct sock *sk) 579 { 580 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 581 582 if (ops) 583 ops->sock_delattr(sk); 584 } 585 586 /** 587 * calipso_req_setattr - Add a CALIPSO option to a connection request socket 588 * @req: the connection request socket 589 * @doi_def: the CALIPSO DOI to use 590 * @secattr: the specific security attributes of the socket 591 * 592 * Description: 593 * Set the CALIPSO option on the given socket using the DOI definition and 594 * security attributes passed to the function. Returns zero on success and 595 * negative values on failure. 596 * 597 */ 598 int calipso_req_setattr(struct request_sock *req, 599 const struct calipso_doi *doi_def, 600 const struct netlbl_lsm_secattr *secattr) 601 { 602 int ret_val = -ENOMSG; 603 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 604 605 if (ops) 606 ret_val = ops->req_setattr(req, doi_def, secattr); 607 return ret_val; 608 } 609 610 /** 611 * calipso_req_delattr - Delete the CALIPSO option from a request socket 612 * @reg: the request socket 613 * 614 * Description: 615 * Removes the CALIPSO option from a request socket, if present. 616 * 617 */ 618 void calipso_req_delattr(struct request_sock *req) 619 { 620 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 621 622 if (ops) 623 ops->req_delattr(req); 624 } 625 626 /** 627 * calipso_optptr - Find the CALIPSO option in the packet 628 * @skb: the packet 629 * 630 * Description: 631 * Parse the packet's IP header looking for a CALIPSO option. Returns a pointer 632 * to the start of the CALIPSO option on success, NULL if one if not found. 633 * 634 */ 635 unsigned char *calipso_optptr(const struct sk_buff *skb) 636 { 637 unsigned char *ret_val = NULL; 638 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 639 640 if (ops) 641 ret_val = ops->skbuff_optptr(skb); 642 return ret_val; 643 } 644 645 /** 646 * calipso_getattr - Get the security attributes from a memory block. 647 * @calipso: the CALIPSO option 648 * @secattr: the security attributes 649 * 650 * Description: 651 * Inspect @calipso and return the security attributes in @secattr. 652 * Returns zero on success and negative values on failure. 653 * 654 */ 655 int calipso_getattr(const unsigned char *calipso, 656 struct netlbl_lsm_secattr *secattr) 657 { 658 int ret_val = -ENOMSG; 659 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 660 661 if (ops) 662 ret_val = ops->opt_getattr(calipso, secattr); 663 return ret_val; 664 } 665 666 /** 667 * calipso_skbuff_setattr - Set the CALIPSO option on a packet 668 * @skb: the packet 669 * @doi_def: the CALIPSO DOI to use 670 * @secattr: the security attributes 671 * 672 * Description: 673 * Set the CALIPSO option on the given packet based on the security attributes. 674 * Returns a pointer to the IP header on success and NULL on failure. 675 * 676 */ 677 int calipso_skbuff_setattr(struct sk_buff *skb, 678 const struct calipso_doi *doi_def, 679 const struct netlbl_lsm_secattr *secattr) 680 { 681 int ret_val = -ENOMSG; 682 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 683 684 if (ops) 685 ret_val = ops->skbuff_setattr(skb, doi_def, secattr); 686 return ret_val; 687 } 688 689 /** 690 * calipso_skbuff_delattr - Delete any CALIPSO options from a packet 691 * @skb: the packet 692 * 693 * Description: 694 * Removes any and all CALIPSO options from the given packet. Returns zero on 695 * success, negative values on failure. 696 * 697 */ 698 int calipso_skbuff_delattr(struct sk_buff *skb) 699 { 700 int ret_val = -ENOMSG; 701 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 702 703 if (ops) 704 ret_val = ops->skbuff_delattr(skb); 705 return ret_val; 706 } 707 708 /** 709 * calipso_cache_invalidate - Invalidates the current CALIPSO cache 710 * 711 * Description: 712 * Invalidates and frees any entries in the CALIPSO cache. Returns zero on 713 * success and negative values on failure. 714 * 715 */ 716 void calipso_cache_invalidate(void) 717 { 718 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 719 720 if (ops) 721 ops->cache_invalidate(); 722 } 723 724 /** 725 * calipso_cache_add - Add an entry to the CALIPSO cache 726 * @calipso_ptr: the CALIPSO option 727 * @secattr: the packet's security attributes 728 * 729 * Description: 730 * Add a new entry into the CALIPSO label mapping cache. 731 * Returns zero on success, negative values on failure. 732 * 733 */ 734 int calipso_cache_add(const unsigned char *calipso_ptr, 735 const struct netlbl_lsm_secattr *secattr) 736 737 { 738 int ret_val = -ENOMSG; 739 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 740 741 if (ops) 742 ret_val = ops->cache_add(calipso_ptr, secattr); 743 return ret_val; 744 } 745