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