linux/net/netlabel/netlabel_calipso.c
<<
>>
Prefs
   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() */
  50struct 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() */
  57struct netlbl_domhsh_walk_arg {
  58        struct netlbl_audit *audit_info;
  59        u32 doi;
  60};
  61
  62/* NetLabel Generic NETLINK CALIPSO family */
  63static struct genl_family netlbl_calipso_gnl_family = {
  64        .id = GENL_ID_GENERATE,
  65        .hdrsize = 0,
  66        .name = NETLBL_NLTYPE_CALIPSO_NAME,
  67        .version = NETLBL_PROTO_VERSION,
  68        .maxattr = NLBL_CALIPSO_A_MAX,
  69};
  70
  71/* NetLabel Netlink attribute policy */
  72static const struct nla_policy calipso_genl_policy[NLBL_CALIPSO_A_MAX + 1] = {
  73        [NLBL_CALIPSO_A_DOI] = { .type = NLA_U32 },
  74        [NLBL_CALIPSO_A_MTYPE] = { .type = NLA_U32 },
  75};
  76
  77/* NetLabel Command Handlers
  78 */
  79/**
  80 * netlbl_calipso_add_pass - Adds a CALIPSO pass DOI definition
  81 * @info: the Generic NETLINK info block
  82 * @audit_info: NetLabel audit information
  83 *
  84 * Description:
  85 * Create a new CALIPSO_MAP_PASS DOI definition based on the given ADD message
  86 * and add it to the CALIPSO engine.  Return zero on success and non-zero on
  87 * error.
  88 *
  89 */
  90static int netlbl_calipso_add_pass(struct genl_info *info,
  91                                   struct netlbl_audit *audit_info)
  92{
  93        int ret_val;
  94        struct calipso_doi *doi_def = NULL;
  95
  96        doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
  97        if (!doi_def)
  98                return -ENOMEM;
  99        doi_def->type = CALIPSO_MAP_PASS;
 100        doi_def->doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]);
 101        ret_val = calipso_doi_add(doi_def, audit_info);
 102        if (ret_val != 0)
 103                calipso_doi_free(doi_def);
 104
 105        return ret_val;
 106}
 107
 108/**
 109 * netlbl_calipso_add - Handle an ADD message
 110 * @skb: the NETLINK buffer
 111 * @info: the Generic NETLINK info block
 112 *
 113 * Description:
 114 * Create a new DOI definition based on the given ADD message and add it to the
 115 * CALIPSO engine.  Returns zero on success, negative values on failure.
 116 *
 117 */
 118static int netlbl_calipso_add(struct sk_buff *skb, struct genl_info *info)
 119
 120{
 121        int ret_val = -EINVAL;
 122        struct netlbl_audit audit_info;
 123
 124        if (!info->attrs[NLBL_CALIPSO_A_DOI] ||
 125            !info->attrs[NLBL_CALIPSO_A_MTYPE])
 126                return -EINVAL;
 127
 128        netlbl_netlink_auditinfo(skb, &audit_info);
 129        switch (nla_get_u32(info->attrs[NLBL_CALIPSO_A_MTYPE])) {
 130        case CALIPSO_MAP_PASS:
 131                ret_val = netlbl_calipso_add_pass(info, &audit_info);
 132                break;
 133        }
 134        if (ret_val == 0)
 135                atomic_inc(&netlabel_mgmt_protocount);
 136
 137        return ret_val;
 138}
 139
 140/**
 141 * netlbl_calipso_list - Handle a LIST message
 142 * @skb: the NETLINK buffer
 143 * @info: the Generic NETLINK info block
 144 *
 145 * Description:
 146 * Process a user generated LIST message and respond accordingly.
 147 * Returns zero on success and negative values on error.
 148 *
 149 */
 150static int netlbl_calipso_list(struct sk_buff *skb, struct genl_info *info)
 151{
 152        int ret_val;
 153        struct sk_buff *ans_skb = NULL;
 154        void *data;
 155        u32 doi;
 156        struct calipso_doi *doi_def;
 157
 158        if (!info->attrs[NLBL_CALIPSO_A_DOI]) {
 159                ret_val = -EINVAL;
 160                goto list_failure;
 161        }
 162
 163        doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]);
 164
 165        doi_def = calipso_doi_getdef(doi);
 166        if (!doi_def) {
 167                ret_val = -EINVAL;
 168                goto list_failure;
 169        }
 170
 171        ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 172        if (!ans_skb) {
 173                ret_val = -ENOMEM;
 174                goto list_failure_put;
 175        }
 176        data = genlmsg_put_reply(ans_skb, info, &netlbl_calipso_gnl_family,
 177                                 0, NLBL_CALIPSO_C_LIST);
 178        if (!data) {
 179                ret_val = -ENOMEM;
 180                goto list_failure_put;
 181        }
 182
 183        ret_val = nla_put_u32(ans_skb, NLBL_CALIPSO_A_MTYPE, doi_def->type);
 184        if (ret_val != 0)
 185                goto list_failure_put;
 186
 187        calipso_doi_putdef(doi_def);
 188
 189        genlmsg_end(ans_skb, data);
 190        return genlmsg_reply(ans_skb, info);
 191
 192list_failure_put:
 193        calipso_doi_putdef(doi_def);
 194list_failure:
 195        kfree_skb(ans_skb);
 196        return ret_val;
 197}
 198
 199/**
 200 * netlbl_calipso_listall_cb - calipso_doi_walk() callback for LISTALL
 201 * @doi_def: the CALIPSO DOI definition
 202 * @arg: the netlbl_calipso_doiwalk_arg structure
 203 *
 204 * Description:
 205 * This function is designed to be used as a callback to the
 206 * calipso_doi_walk() function for use in generating a response for a LISTALL
 207 * message.  Returns the size of the message on success, negative values on
 208 * failure.
 209 *
 210 */
 211static int netlbl_calipso_listall_cb(struct calipso_doi *doi_def, void *arg)
 212{
 213        int ret_val = -ENOMEM;
 214        struct netlbl_calipso_doiwalk_arg *cb_arg = arg;
 215        void *data;
 216
 217        data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
 218                           cb_arg->seq, &netlbl_calipso_gnl_family,
 219                           NLM_F_MULTI, NLBL_CALIPSO_C_LISTALL);
 220        if (!data)
 221                goto listall_cb_failure;
 222
 223        ret_val = nla_put_u32(cb_arg->skb, NLBL_CALIPSO_A_DOI, doi_def->doi);
 224        if (ret_val != 0)
 225                goto listall_cb_failure;
 226        ret_val = nla_put_u32(cb_arg->skb,
 227                              NLBL_CALIPSO_A_MTYPE,
 228                              doi_def->type);
 229        if (ret_val != 0)
 230                goto listall_cb_failure;
 231
 232        genlmsg_end(cb_arg->skb, data);
 233        return 0;
 234
 235listall_cb_failure:
 236        genlmsg_cancel(cb_arg->skb, data);
 237        return ret_val;
 238}
 239
 240/**
 241 * netlbl_calipso_listall - Handle a LISTALL message
 242 * @skb: the NETLINK buffer
 243 * @cb: the NETLINK callback
 244 *
 245 * Description:
 246 * Process a user generated LISTALL message and respond accordingly.  Returns
 247 * zero on success and negative values on error.
 248 *
 249 */
 250static int netlbl_calipso_listall(struct sk_buff *skb,
 251                                  struct netlink_callback *cb)
 252{
 253        struct netlbl_calipso_doiwalk_arg cb_arg;
 254        u32 doi_skip = cb->args[0];
 255
 256        cb_arg.nl_cb = cb;
 257        cb_arg.skb = skb;
 258        cb_arg.seq = cb->nlh->nlmsg_seq;
 259
 260        calipso_doi_walk(&doi_skip, netlbl_calipso_listall_cb, &cb_arg);
 261
 262        cb->args[0] = doi_skip;
 263        return skb->len;
 264}
 265
 266/**
 267 * netlbl_calipso_remove_cb - netlbl_calipso_remove() callback for REMOVE
 268 * @entry: LSM domain mapping entry
 269 * @arg: the netlbl_domhsh_walk_arg structure
 270 *
 271 * Description:
 272 * This function is intended for use by netlbl_calipso_remove() as the callback
 273 * for the netlbl_domhsh_walk() function; it removes LSM domain map entries
 274 * which are associated with the CALIPSO DOI specified in @arg.  Returns zero on
 275 * success, negative values on failure.
 276 *
 277 */
 278static int netlbl_calipso_remove_cb(struct netlbl_dom_map *entry, void *arg)
 279{
 280        struct netlbl_domhsh_walk_arg *cb_arg = arg;
 281
 282        if (entry->def.type == NETLBL_NLTYPE_CALIPSO &&
 283            entry->def.calipso->doi == cb_arg->doi)
 284                return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info);
 285
 286        return 0;
 287}
 288
 289/**
 290 * netlbl_calipso_remove - Handle a REMOVE message
 291 * @skb: the NETLINK buffer
 292 * @info: the Generic NETLINK info block
 293 *
 294 * Description:
 295 * Process a user generated REMOVE message and respond accordingly.  Returns
 296 * zero on success, negative values on failure.
 297 *
 298 */
 299static int netlbl_calipso_remove(struct sk_buff *skb, struct genl_info *info)
 300{
 301        int ret_val = -EINVAL;
 302        struct netlbl_domhsh_walk_arg cb_arg;
 303        struct netlbl_audit audit_info;
 304        u32 skip_bkt = 0;
 305        u32 skip_chain = 0;
 306
 307        if (!info->attrs[NLBL_CALIPSO_A_DOI])
 308                return -EINVAL;
 309
 310        netlbl_netlink_auditinfo(skb, &audit_info);
 311        cb_arg.doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]);
 312        cb_arg.audit_info = &audit_info;
 313        ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
 314                                     netlbl_calipso_remove_cb, &cb_arg);
 315        if (ret_val == 0 || ret_val == -ENOENT) {
 316                ret_val = calipso_doi_remove(cb_arg.doi, &audit_info);
 317                if (ret_val == 0)
 318                        atomic_dec(&netlabel_mgmt_protocount);
 319        }
 320
 321        return ret_val;
 322}
 323
 324/* NetLabel Generic NETLINK Command Definitions
 325 */
 326
 327static const struct genl_ops netlbl_calipso_ops[] = {
 328        {
 329        .cmd = NLBL_CALIPSO_C_ADD,
 330        .flags = GENL_ADMIN_PERM,
 331        .policy = calipso_genl_policy,
 332        .doit = netlbl_calipso_add,
 333        .dumpit = NULL,
 334        },
 335        {
 336        .cmd = NLBL_CALIPSO_C_REMOVE,
 337        .flags = GENL_ADMIN_PERM,
 338        .policy = calipso_genl_policy,
 339        .doit = netlbl_calipso_remove,
 340        .dumpit = NULL,
 341        },
 342        {
 343        .cmd = NLBL_CALIPSO_C_LIST,
 344        .flags = 0,
 345        .policy = calipso_genl_policy,
 346        .doit = netlbl_calipso_list,
 347        .dumpit = NULL,
 348        },
 349        {
 350        .cmd = NLBL_CALIPSO_C_LISTALL,
 351        .flags = 0,
 352        .policy = calipso_genl_policy,
 353        .doit = NULL,
 354        .dumpit = netlbl_calipso_listall,
 355        },
 356};
 357
 358/* NetLabel Generic NETLINK Protocol Functions
 359 */
 360
 361/**
 362 * netlbl_calipso_genl_init - Register the CALIPSO NetLabel component
 363 *
 364 * Description:
 365 * Register the CALIPSO packet NetLabel component with the Generic NETLINK
 366 * mechanism.  Returns zero on success, negative values on failure.
 367 *
 368 */
 369int __init netlbl_calipso_genl_init(void)
 370{
 371        return genl_register_family_with_ops(&netlbl_calipso_gnl_family,
 372                                             netlbl_calipso_ops);
 373}
 374
 375static 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 */
 384const struct netlbl_calipso_ops *
 385netlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops)
 386{
 387        return xchg(&calipso_ops, ops);
 388}
 389EXPORT_SYMBOL(netlbl_calipso_ops_register);
 390
 391static const struct netlbl_calipso_ops *netlbl_calipso_ops_get(void)
 392{
 393        return ACCESS_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 */
 409int 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 */
 428void 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 */
 447int 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 */
 467struct 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 */
 485void 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 */
 506int 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 */
 530int 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 */
 554int 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 */
 574void 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 */
 594int 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 */
 614void 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 */
 631unsigned 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 */
 651int 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 */
 673int 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 */
 694int 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 */
 712void 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 */
 730int 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