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