// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * CALIPSO - Common Architecture Label IPv6 Security Option
 *
 * This is an implementation of the CALIPSO protocol as specified in
 * RFC 5570.
 *
 * Authors: Paul Moore <paul.moore@hp.com>
 *          Huw Davies <huw@codeweavers.com>
 */

/* (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
 * (c) Copyright Huw Davies <huw@codeweavers.com>, 2015
 */

#include <linux/init.h>
#include <linux/types.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/jhash.h>
#include <linux/audit.h>
#include <linux/slab.h>
#include <net/ip.h>
#include <net/icmp.h>
#include <net/tcp.h>
#include <net/netlabel.h>
#include <net/calipso.h>
#include <linux/atomic.h>
#include <linux/bug.h>
#include <asm/unaligned.h>
#include <linux/crc-ccitt.h>

/* Maximium size of the calipso option including
 * the two-byte TLV header.
 */
#define CALIPSO_OPT_LEN_MAX (2 + 252)

/* Size of the minimum calipso option including
 * the two-byte TLV header.
 */
#define CALIPSO_HDR_LEN (2 + 8)

/* Maximium size of the calipso option including
 * the two-byte TLV header and upto 3 bytes of
 * leading pad and 7 bytes of trailing pad.
 */
#define CALIPSO_OPT_LEN_MAX_WITH_PAD (3 + CALIPSO_OPT_LEN_MAX + 7)

 /* Maximium size of u32 aligned buffer required to hold calipso
  * option.  Max of 3 initial pad bytes starting from buffer + 3.
  * i.e. the worst case is when the previous tlv finishes on 4n + 3.
  */
#define CALIPSO_MAX_BUFFER (6 + CALIPSO_OPT_LEN_MAX)

/* List of available DOI definitions */
static DEFINE_SPINLOCK(calipso_doi_list_lock);
static LIST_HEAD(calipso_doi_list);

/* Label mapping cache */
int calipso_cache_enabled = 1;
int calipso_cache_bucketsize = 10;
#define CALIPSO_CACHE_BUCKETBITS     7
#define CALIPSO_CACHE_BUCKETS        BIT(CALIPSO_CACHE_BUCKETBITS)
#define CALIPSO_CACHE_REORDERLIMIT   10
struct calipso_map_cache_bkt {
	spinlock_t lock;
	u32 size;
	struct list_head list;
};

struct calipso_map_cache_entry {
	u32 hash;
	unsigned char *key;
	size_t key_len;

	struct netlbl_lsm_cache *lsm_data;

	u32 activity;
	struct list_head list;
};

static struct calipso_map_cache_bkt *calipso_cache;

static void calipso_cache_invalidate(void);
static void calipso_doi_putdef(struct calipso_doi *doi_def);

/* Label Mapping Cache Functions
 */

/**
 * calipso_cache_entry_free - Frees a cache entry
 * @entry: the entry to free
 *
 * Description:
 * This function frees the memory associated with a cache entry including the
 * LSM cache data if there are no longer any users, i.e. reference count == 0.
 *
 */
static void calipso_cache_entry_free(struct calipso_map_cache_entry *entry)
{
	if (entry->lsm_data)
		netlbl_secattr_cache_free(entry->lsm_data);
	kfree(entry->key);
	kfree(entry);
}

/**
 * calipso_map_cache_hash - Hashing function for the CALIPSO cache
 * @key: the hash key
 * @key_len: the length of the key in bytes
 *
 * Description:
 * The CALIPSO tag hashing function.  Returns a 32-bit hash value.
 *
 */
static u32 calipso_map_cache_hash(const unsigned char *key, u32 key_len)
{
	return jhash(key, key_len, 0);
}

/**
 * calipso_cache_init - Initialize the CALIPSO cache
 *
 * Description:
 * Initializes the CALIPSO label mapping cache, this function should be called
 * before any of the other functions defined in this file.  Returns zero on
 * success, negative values on error.
 *
 */
static int __init calipso_cache_init(void)
{
	u32 iter;

	calipso_cache = kcalloc(CALIPSO_CACHE_BUCKETS,
				sizeof(struct calipso_map_cache_bkt),
				GFP_KERNEL);
	if (!calipso_cache)
		return -ENOMEM;

	for (iter = 0; iter < CALIPSO_CACHE_BUCKETS; iter++) {
		spin_lock_init(&calipso_cache[iter].lock);
		calipso_cache[iter].size = 0;
		INIT_LIST_HEAD(&calipso_cache[iter].list);
	}

	return 0;
}

/**
 * calipso_cache_invalidate - Invalidates the current CALIPSO cache
 *
 * Description:
 * Invalidates and frees any entries in the CALIPSO cache.  Returns zero on
 * success and negative values on failure.
 *
 */
static void calipso_cache_invalidate(void)
{
	struct calipso_map_cache_entry *entry, *tmp_entry;
	u32 iter;

	for (iter = 0; iter < CALIPSO_CACHE_BUCKETS; iter++) {
		spin_lock_bh(&calipso_cache[iter].lock);
		list_for_each_entry_safe(entry,
					 tmp_entry,
					 &calipso_cache[iter].list, list) {
			list_del(&entry->list);
			calipso_cache_entry_free(entry);
		}
		calipso_cache[iter].size = 0;
		spin_unlock_bh(&calipso_cache[iter].lock);
	}
}

/**
 * calipso_cache_check - Check the CALIPSO cache for a label mapping
 * @key: the buffer to check
 * @key_len: buffer length in bytes
 * @secattr: the security attribute struct to use
 *
 * Description:
 * This function checks the cache to see if a label mapping already exists for
 * the given key.  If there is a match then the cache is adjusted and the
 * @secattr struct is populated with the correct LSM security attributes.  The
 * cache is adjusted in the following manner if the entry is not already the
 * first in the cache bucket:
 *
 *  1. The cache entry's activity counter is incremented
 *  2. The previous (higher ranking) entry's activity counter is decremented
 *  3. If the difference between the two activity counters is geater than
 *     CALIPSO_CACHE_REORDERLIMIT the two entries are swapped
 *
 * Returns zero on success, -ENOENT for a cache miss, and other negative values
 * on error.
 *
 */
static int calipso_cache_check(const unsigned char *key,
			       u32 key_len,
			       struct netlbl_lsm_secattr *secattr)
{
	u32 bkt;
	struct calipso_map_cache_entry *entry;
	struct calipso_map_cache_entry *prev_entry = NULL;
	u32 hash;

	if (!calipso_cache_enabled)
		return -ENOENT;

	hash = calipso_map_cache_hash(key, key_len);
	bkt = hash & (CALIPSO_CACHE_BUCKETS - 1);
	spin_lock_bh(&calipso_cache[bkt].lock);
	list_for_each_entry(entry, &calipso_cache[bkt].list, list) {
		if (entry->hash == hash &&
		    entry->key_len == key_len &&
		    memcmp(entry->key, key, key_len) == 0) {
			entry->activity += 1;
			refcount_inc(&entry->lsm_data->refcount);
			secattr->cache = entry->lsm_data;
			secattr->flags |= NETLBL_SECATTR_CACHE;
			secattr->type = NETLBL_NLTYPE_CALIPSO;
			if (!prev_entry) {
				spin_unlock_bh(&calipso_cache[bkt].lock);
				return 0;
			}

			if (prev_entry->activity > 0)
				prev_entry->activity -= 1;
			if (entry->activity > prev_entry->activity &&
			    entry->activity - prev_entry->activity >
			    CALIPSO_CACHE_REORDERLIMIT) {
				__list_del(entry->list.prev, entry->list.next);
				__list_add(&entry->list,
					   prev_entry->list.prev,
					   &prev_entry->list);
			}

			spin_unlock_bh(&calipso_cache[bkt].lock);
			return 0;
		}
		prev_entry = entry;
	}
	spin_unlock_bh(&calipso_cache[bkt].lock);

	return -ENOENT;
}

/**
 * calipso_cache_add - Add an entry to the CALIPSO cache
 * @calipso_ptr: the CALIPSO option
 * @secattr: the packet's security attributes
 *
 * Description:
 * Add a new entry into the CALIPSO label mapping cache.  Add the new entry to
 * head of the cache bucket's list, if the cache bucket is out of room remove
 * the last entry in the list first.  It is important to note that there is
 * currently no checking for duplicate keys.  Returns zero on success,
 * negative values on failure.  The key stored starts at calipso_ptr + 2,
 * i.e. the type and length bytes are not stored, this corresponds to
 * calipso_ptr[1] bytes of data.
 *
 */
static int calipso_cache_add(const unsigned char *calipso_ptr,
			     const struct netlbl_lsm_secattr *secattr)
{
	int ret_val = -EPERM;
	u32 bkt;
	struct calipso_map_cache_entry *entry = NULL;
	struct calipso_map_cache_entry *old_entry = NULL;
	u32 calipso_ptr_len;

	if (!calipso_cache_enabled || calipso_cache_bucketsize <= 0)
		return 0;

	calipso_ptr_len = calipso_ptr[1];

	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
	if (!entry)
		return -ENOMEM;
	entry->key = kmemdup(calipso_ptr + 2, calipso_ptr_len, GFP_ATOMIC);
	if (!entry->key) {
		ret_val = -ENOMEM;
		goto cache_add_failure;
	}
	entry->key_len = calipso_ptr_len;
	entry->hash = calipso_map_cache_hash(calipso_ptr, calipso_ptr_len);
	refcount_inc(&secattr->cache->refcount);
	entry->lsm_data = secattr->cache;

	bkt = entry->hash & (CALIPSO_CACHE_BUCKETS - 1);
	spin_lock_bh(&calipso_cache[bkt].lock);
	if (calipso_cache[bkt].size < calipso_cache_bucketsize) {
		list_add(&entry->list, &calipso_cache[bkt].list);
		calipso_cache[bkt].size += 1;
	} else {
		old_entry = list_entry(calipso_cache[bkt].list.prev,
				       struct calipso_map_cache_entry, list);
		list_del(&old_entry->list);
		list_add(&entry->list, &calipso_cache[bkt].list);
		calipso_cache_entry_free(old_entry);
	}
	spin_unlock_bh(&calipso_cache[bkt].lock);

	return 0;

cache_add_failure:
	if (entry)
		calipso_cache_entry_free(entry);
	return ret_val;
}

/* DOI List Functions
 */

/**
 * calipso_doi_search - Searches for a DOI definition
 * @doi: the DOI to search for
 *
 * Description:
 * Search the DOI definition list for a DOI definition with a DOI value that
 * matches @doi.  The caller is responsible for calling rcu_read_[un]lock().
 * Returns a pointer to the DOI definition on success and NULL on failure.
 */
static struct calipso_doi *calipso_doi_search(u32 doi)
{
	struct calipso_doi *iter;

	list_for_each_entry_rcu(iter, &calipso_doi_list, list)
		if (iter->doi == doi && refcount_read(&iter->refcount))
			return iter;
	return NULL;
}

/**
 * calipso_doi_add - Add a new DOI to the CALIPSO protocol engine
 * @doi_def: the DOI structure
 * @audit_info: NetLabel audit information
 *
 * Description:
 * The caller defines a new DOI for use by the CALIPSO engine and calls this
 * function to add it to the list of acceptable domains.  The caller must
 * ensure that the mapping table specified in @doi_def->map meets all of the
 * requirements of the mapping type (see calipso.h for details).  Returns
 * zero on success and non-zero on failure.
 *
 */
static int calipso_doi_add(struct calipso_doi *doi_def,
			   struct netlbl_audit *audit_info)
{
	int ret_val = -EINVAL;
	u32 doi;
	u32 doi_type;
	struct audit_buffer *audit_buf;

	doi = doi_def->doi;
	doi_type = doi_def->type;

	if (doi_def->doi == CALIPSO_DOI_UNKNOWN)
		goto doi_add_return;

	refcount_set(&doi_def->refcount, 1);

	spin_lock(&calipso_doi_list_lock);
	if (calipso_doi_search(doi_def->doi)) {
		spin_unlock(&calipso_doi_list_lock);
		ret_val = -EEXIST;
		goto doi_add_return;
	}
	list_add_tail_rcu(&doi_def->list, &calipso_doi_list);
	spin_unlock(&calipso_doi_list_lock);
	ret_val = 0;

doi_add_return:
	audit_buf = netlbl_audit_start(AUDIT_MAC_CALIPSO_ADD, audit_info);
	if (audit_buf) {
		const char *type_str;

		switch (doi_type) {
		case CALIPSO_MAP_PASS:
			type_str = "pass";
			break;
		default:
			type_str = "(unknown)";
		}
		audit_log_format(audit_buf,
				 " calipso_doi=%u calipso_type=%s res=%u",
				 doi, type_str, ret_val == 0 ? 1 : 0);
		audit_log_end(audit_buf);
	}

	return ret_val;
}

/**
 * calipso_doi_free - Frees a DOI definition
 * @doi_def: the DOI definition
 *
 * Description:
 * This function frees all of the memory associated with a DOI definition.
 *
 */
static void calipso_doi_free(struct calipso_doi *doi_def)
{
	kfree(doi_def);
}

/**
 * calipso_doi_free_rcu - Frees a DOI definition via the RCU pointer
 * @entry: the entry's RCU field
 *
 * Description:
 * This function is designed to be used as a callback to the call_rcu()
 * function so that the memory allocated to the DOI definition can be released
 * safely.
 *
 */
static void calipso_doi_free_rcu(struct rcu_head *entry)
{
	struct calipso_doi *doi_def;

	doi_def = container_of(entry, struct calipso_doi, rcu);
	calipso_doi_free(doi_def);
}

/**
 * calipso_doi_remove - Remove an existing DOI from the CALIPSO protocol engine
 * @doi: the DOI value
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Removes a DOI definition from the CALIPSO engine.  The NetLabel routines will
 * be called to release their own LSM domain mappings as well as our own
 * domain list.  Returns zero on success and negative values on failure.
 *
 */
static int calipso_doi_remove(u32 doi, struct netlbl_audit *audit_info)
{
	int ret_val;
	struct calipso_doi *doi_def;
	struct audit_buffer *audit_buf;

	spin_lock(&calipso_doi_list_lock);
	doi_def = calipso_doi_search(doi);
	if (!doi_def) {
		spin_unlock(&calipso_doi_list_lock);
		ret_val = -ENOENT;
		goto doi_remove_return;
	}
	list_del_rcu(&doi_def->list);
	spin_unlock(&calipso_doi_list_lock);

	calipso_doi_putdef(doi_def);
	ret_val = 0;

doi_remove_return:
	audit_buf = netlbl_audit_start(AUDIT_MAC_CALIPSO_DEL, audit_info);
	if (audit_buf) {
		audit_log_format(audit_buf,
				 " calipso_doi=%u res=%u",
				 doi, ret_val == 0 ? 1 : 0);
		audit_log_end(audit_buf);
	}

	return ret_val;
}

/**
 * calipso_doi_getdef - Returns a reference to a valid DOI definition
 * @doi: the DOI value
 *
 * Description:
 * Searches for a valid DOI definition and if one is found it is returned to
 * the caller.  Otherwise NULL is returned.  The caller must ensure that
 * calipso_doi_putdef() is called when the caller is done.
 *
 */
static struct calipso_doi *calipso_doi_getdef(u32 doi)
{
	struct calipso_doi *doi_def;

	rcu_read_lock();
	doi_def = calipso_doi_search(doi);
	if (!doi_def)
		goto doi_getdef_return;
	if (!refcount_inc_not_zero(&doi_def->refcount))
		doi_def = NULL;

doi_getdef_return:
	rcu_read_unlock();
	return doi_def;
}

/**
 * calipso_doi_putdef - Releases a reference for the given DOI definition
 * @doi_def: the DOI definition
 *
 * Description:
 * Releases a DOI definition reference obtained from calipso_doi_getdef().
 *
 */
static void calipso_doi_putdef(struct calipso_doi *doi_def)
{
	if (!doi_def)
		return;

	if (!refcount_dec_and_test(&doi_def->refcount))
		return;

	calipso_cache_invalidate();
	call_rcu(&doi_def->rcu, calipso_doi_free_rcu);
}

/**
 * calipso_doi_walk - Iterate through the DOI definitions
 * @skip_cnt: skip past this number of DOI definitions, updated
 * @callback: callback for each DOI definition
 * @cb_arg: argument for the callback function
 *
 * Description:
 * Iterate over the DOI definition list, skipping the first @skip_cnt entries.
 * For each entry call @callback, if @callback returns a negative value stop
 * 'walking' through the list and return.  Updates the value in @skip_cnt upon
 * return.  Returns zero on success, negative values on failure.
 *
 */
static int calipso_doi_walk(u32 *skip_cnt,
			    int (*callback)(struct calipso_doi *doi_def,
					    void *arg),
			    void *cb_arg)
{
	int ret_val = -ENOENT;
	u32 doi_cnt = 0;
	struct calipso_doi *iter_doi;

	rcu_read_lock();
	list_for_each_entry_rcu(iter_doi, &calipso_doi_list, list)
		if (refcount_read(&iter_doi->refcount) > 0) {
			if (doi_cnt++ < *skip_cnt)
				continue;
			ret_val = callback(iter_doi, cb_arg);
			if (ret_val < 0) {
				doi_cnt--;
				goto doi_walk_return;
			}
		}

doi_walk_return:
	rcu_read_unlock();
	*skip_cnt = doi_cnt;
	return ret_val;
}

/**
 * calipso_validate - Validate a CALIPSO option
 * @skb: the packet
 * @option: the start of the option
 *
 * Description:
 * This routine is called to validate a CALIPSO option.
 * If the option is valid then %true is returned, otherwise
 * %false is returned.
 *
 * The caller should have already checked that the length of the
 * option (including the TLV header) is >= 10 and that the catmap
 * length is consistent with the option length.
 *
 * We leave checks on the level and categories to the socket layer.
 */
bool calipso_validate(const struct sk_buff *skb, const unsigned char *option)
{
	struct calipso_doi *doi_def;
	bool ret_val;
	u16 crc, len = option[1] + 2;
	static const u8 zero[2];

	/* The original CRC runs over the option including the TLV header
	 * with the CRC-16 field (at offset 8) zeroed out. */
	crc = crc_ccitt(0xffff, option, 8);
	crc = crc_ccitt(crc, zero, sizeof(zero));
	if (len > 10)
		crc = crc_ccitt(crc, option + 10, len - 10);
	crc = ~crc;
	if (option[8] != (crc & 0xff) || option[9] != ((crc >> 8) & 0xff))
		return false;

	rcu_read_lock();
	doi_def = calipso_doi_search(get_unaligned_be32(option + 2));
	ret_val = !!doi_def;
	rcu_read_unlock();

	return ret_val;
}

/**
 * calipso_map_cat_hton - Perform a category mapping from host to network
 * @doi_def: the DOI definition
 * @secattr: the security attributes
 * @net_cat: the zero'd out category bitmap in network/CALIPSO format
 * @net_cat_len: the length of the CALIPSO bitmap in bytes
 *
 * Description:
 * Perform a label mapping to translate a local MLS category bitmap to the
 * correct CALIPSO bitmap using the given DOI definition.  Returns the minimum
 * size in bytes of the network bitmap on success, negative values otherwise.
 *
 */
static int calipso_map_cat_hton(const struct calipso_doi *doi_def,
				const struct netlbl_lsm_secattr *secattr,
				unsigned char *net_cat,
				u32 net_cat_len)
{
	int spot = -1;
	u32 net_spot_max = 0;
	u32 net_clen_bits = net_cat_len * 8;

	for (;;) {
		spot = netlbl_catmap_walk(secattr->attr.mls.cat,
					  spot + 1);
		if (spot < 0)
			break;
		if (spot >= net_clen_bits)
			return -ENOSPC;
		netlbl_bitmap_setbit(net_cat, spot, 1);

		if (spot > net_spot_max)
			net_spot_max = spot;
	}

	return (net_spot_max / 32 + 1) * 4;
}

/**
 * calipso_map_cat_ntoh - Perform a category mapping from network to host
 * @doi_def: the DOI definition
 * @net_cat: the category bitmap in network/CALIPSO format
 * @net_cat_len: the length of the CALIPSO bitmap in bytes
 * @secattr: the security attributes
 *
 * Description:
 * Perform a label mapping to translate a CALIPSO bitmap to the correct local
 * MLS category bitmap using the given DOI definition.  Returns zero on
 * success, negative values on failure.
 *
 */
static int calipso_map_cat_ntoh(const struct calipso_doi *doi_def,
				const unsigned char *net_cat,
				u32 net_cat_len,
				struct netlbl_lsm_secattr *secattr)
{
	int ret_val;
	int spot = -1;
	u32 net_clen_bits = net_cat_len * 8;

	for (;;) {
		spot = netlbl_bitmap_walk(net_cat,
					  net_clen_bits,
					  spot + 1,
					  1);
		if (spot < 0) {
			if (spot == -2)
				return -EFAULT;
			return 0;
		}

		ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat,
					       spot,
					       GFP_ATOMIC);
		if (ret_val != 0)
			return ret_val;
	}

	return -EINVAL;
}

/**
 * calipso_pad_write - Writes pad bytes in TLV format
 * @buf: the buffer
 * @offset: offset from start of buffer to write padding
 * @count: number of pad bytes to write
 *
 * Description:
 * Write @count bytes of TLV padding into @buffer starting at offset @offset.
 * @count should be less than 8 - see RFC 4942.
 *
 */
static int calipso_pad_write(unsigned char *buf, unsigned int offset,
			     unsigned int count)
{
	if (WARN_ON_ONCE(count >= 8))
		return -EINVAL;

	switch (count) {
	case 0:
		break;
	case 1:
		buf[offset] = IPV6_TLV_PAD1;
		break;
	default:
		buf[offset] = IPV6_TLV_PADN;
		buf[offset + 1] = count - 2;
		if (count > 2)
			memset(buf + offset + 2, 0, count - 2);
		break;
	}
	return 0;
}

/**
 * calipso_genopt - Generate a CALIPSO option
 * @buf: the option buffer
 * @start: offset from which to write
 * @buf_len: the size of opt_buf
 * @doi_def: the CALIPSO DOI to use
 * @secattr: the security attributes
 *
 * Description:
 * Generate a CALIPSO option using the DOI definition and security attributes
 * passed to the function. This also generates upto three bytes of leading
 * padding that ensures that the option is 4n + 2 aligned.  It returns the
 * number of bytes written (including any initial padding).
 */
static int calipso_genopt(unsigned char *buf, u32 start, u32 buf_len,
			  const struct calipso_doi *doi_def,
			  const struct netlbl_lsm_secattr *secattr)
{
	int ret_val;
	u32 len, pad;
	u16 crc;
	static const unsigned char padding[4] = {2, 1, 0, 3};
	unsigned char *calipso;

	/* CALIPSO has 4n + 2 alignment */
	pad = padding[start & 3];
	if (buf_len <= start + pad + CALIPSO_HDR_LEN)
		return -ENOSPC;

	if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
		return -EPERM;

	len = CALIPSO_HDR_LEN;

	if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
		ret_val = calipso_map_cat_hton(doi_def,
					       secattr,
					       buf + start + pad + len,
					       buf_len - start - pad - len);
		if (ret_val < 0)
			return ret_val;
		len += ret_val;
	}

	calipso_pad_write(buf, start, pad);
	calipso = buf + start + pad;

	calipso[0] = IPV6_TLV_CALIPSO;
	calipso[1] = len - 2;
	*(__be32 *)(calipso + 2) = htonl(doi_def->doi);
	calipso[6] = (len - CALIPSO_HDR_LEN) / 4;
	calipso[7] = secattr->attr.mls.lvl;
	crc = ~crc_ccitt(0xffff, calipso, len);
	calipso[8] = crc & 0xff;
	calipso[9] = (crc >> 8) & 0xff;
	return pad + len;
}

/* Hop-by-hop hdr helper functions
 */

/**
 * calipso_opt_update - Replaces socket's hop options with a new set
 * @sk: the socket
 * @hop: new hop options
 *
 * Description:
 * Replaces @sk's hop options with @hop.  @hop may be NULL to leave
 * the socket with no hop options.
 *
 */
static int calipso_opt_update(struct sock *sk, struct ipv6_opt_hdr *hop)
{
	struct ipv6_txoptions *old = txopt_get(inet6_sk(sk)), *txopts;

	txopts = ipv6_renew_options(sk, old, IPV6_HOPOPTS, hop);
	txopt_put(old);
	if (IS_ERR(txopts))
		return PTR_ERR(txopts);

	txopts = ipv6_update_options(sk, txopts);
	if (txopts) {
		atomic_sub(txopts->tot_len, &sk->sk_omem_alloc);
		txopt_put(txopts);
	}

	return 0;
}

/**
 * calipso_tlv_len - Returns the length of the TLV
 * @opt: the option header
 * @offset: offset of the TLV within the header
 *
 * Description:
 * Returns the length of the TLV option at offset @offset within
 * the option header @opt.  Checks that the entire TLV fits inside
 * the option header, returns a negative value if this is not the case.
 */
static int calipso_tlv_len(struct ipv6_opt_hdr *opt, unsigned int offset)
{
	unsigned char *tlv = (unsigned char *)opt;
	unsigned int opt_len = ipv6_optlen(opt), tlv_len;

	if (offset < sizeof(*opt) || offset >= opt_len)
		return -EINVAL;
	if (tlv[offset] == IPV6_TLV_PAD1)
		return 1;
	if (offset + 1 >= opt_len)
		return -EINVAL;
	tlv_len = tlv[offset + 1] + 2;
	if (offset + tlv_len > opt_len)
		return -EINVAL;
	return tlv_len;
}

/**
 * calipso_opt_find - Finds the CALIPSO option in an IPv6 hop options header
 * @hop: the hop options header
 * @start: on return holds the offset of any leading padding
 * @end: on return holds the offset of the first non-pad TLV after CALIPSO
 *
 * Description:
 * Finds the space occupied by a CALIPSO option (including any leading and
 * trailing padding).
 *
 * If a CALIPSO option exists set @start and @end to the
 * offsets within @hop of the start of padding before the first
 * CALIPSO option and the end of padding after the first CALIPSO
 * option.  In this case the function returns 0.
 *
 * In the absence of a CALIPSO option, @start and @end will be
 * set to the start and end of any trailing padding in the header.
 * This is useful when appending a new option, as the caller may want
 * to overwrite some of this padding.  In this case the function will
 * return -ENOENT.
 */
static int calipso_opt_find(struct ipv6_opt_hdr *hop, unsigned int *start,
			    unsigned int *end)
{
	int ret_val = -ENOENT, tlv_len;
	unsigned int opt_len, offset, offset_s = 0, offset_e = 0;
	unsigned char *opt = (unsigned char *)hop;

	opt_len = ipv6_optlen(hop);
	offset = sizeof(*hop);

	while (offset < opt_len) {
		tlv_len = calipso_tlv_len(hop, offset);
		if (tlv_len < 0)
			return tlv_len;

		switch (opt[offset]) {
		case IPV6_TLV_PAD1:
		case IPV6_TLV_PADN:
			if (offset_e)
				offset_e = offset;
			break;
		case IPV6_TLV_CALIPSO:
			ret_val = 0;
			offset_e = offset;
			break;
		default:
			if (offset_e == 0)
				offset_s = offset;
			else
				goto out;
		}
		offset += tlv_len;
	}

out:
	if (offset_s)
		*start = offset_s + calipso_tlv_len(hop, offset_s);
	else
		*start = sizeof(*hop);
	if (offset_e)
		*end = offset_e + calipso_tlv_len(hop, offset_e);
	else
		*end = opt_len;

	return ret_val;
}

/**
 * calipso_opt_insert - Inserts a CALIPSO option into an IPv6 hop opt hdr
 * @hop: the original hop options header
 * @doi_def: the CALIPSO DOI to use
 * @secattr: the specific security attributes of the socket
 *
 * Description:
 * Creates a new hop options header based on @hop with a
 * CALIPSO option added to it.  If @hop already contains a CALIPSO
 * option this is overwritten, otherwise the new option is appended
 * after any existing options.  If @hop is NULL then the new header
 * will contain just the CALIPSO option and any needed padding.
 *
 */
static struct ipv6_opt_hdr *
calipso_opt_insert(struct ipv6_opt_hdr *hop,
		   const struct calipso_doi *doi_def,
		   const struct netlbl_lsm_secattr *secattr)
{
	unsigned int start, end, buf_len, pad, hop_len;
	struct ipv6_opt_hdr *new;
	int ret_val;

	if (hop) {
		hop_len = ipv6_optlen(hop);
		ret_val = calipso_opt_find(hop, &start, &end);
		if (ret_val && ret_val != -ENOENT)
			return ERR_PTR(ret_val);
	} else {
		hop_len = 0;
		start = sizeof(*hop);
		end = 0;
	}

	buf_len = hop_len + start - end + CALIPSO_OPT_LEN_MAX_WITH_PAD;
	new = kzalloc(buf_len, GFP_ATOMIC);
	if (!new)
		return ERR_PTR(-ENOMEM);

	if (start > sizeof(*hop))
		memcpy(new, hop, start);
	ret_val = calipso_genopt((unsigned char *)new, start, buf_len, doi_def,
				 secattr);
	if (ret_val < 0) {
		kfree(new);
		return ERR_PTR(ret_val);
	}

	buf_len = start + ret_val;
	/* At this point buf_len aligns to 4n, so (buf_len & 4) pads to 8n */
	pad = ((buf_len & 4) + (end & 7)) & 7;
	calipso_pad_write((unsigned char *)new, buf_len, pad);
	buf_len += pad;

	if (end != hop_len) {
		memcpy((char *)new + buf_len, (char *)hop + end, hop_len - end);
		buf_len += hop_len - end;
	}
	new->nexthdr = 0;
	new->hdrlen = buf_len / 8 - 1;

	return new;
}

/**
 * calipso_opt_del - Removes the CALIPSO option from an option header
 * @hop: the original header
 * @new: the new header
 *
 * Description:
 * Creates a new header based on @hop without any CALIPSO option.  If @hop
 * doesn't contain a CALIPSO option it returns -ENOENT.  If @hop contains
 * no other non-padding options, it returns zero with @new set to NULL.
 * Otherwise it returns zero, creates a new header without the CALIPSO
 * option (and removing as much padding as possible) and returns with
 * @new set to that header.
 *
 */
static int calipso_opt_del(struct ipv6_opt_hdr *hop,
			   struct ipv6_opt_hdr **new)
{
	int ret_val;
	unsigned int start, end, delta, pad, hop_len;

	ret_val = calipso_opt_find(hop, &start, &end);
	if (ret_val)
		return ret_val;

	hop_len = ipv6_optlen(hop);
	if (start == sizeof(*hop) && end == hop_len) {
		/* There's no other option in the header so return NULL */
		*new = NULL;
		return 0;
	}

	delta = (end - start) & ~7;
	*new = kzalloc(hop_len - delta, GFP_ATOMIC);
	if (!*new)
		return -ENOMEM;

	memcpy(*new, hop, start);
	(*new)->hdrlen -= delta / 8;
	pad = (end - start) & 7;
	calipso_pad_write((unsigned char *)*new, start, pad);
	if (end != hop_len)
		memcpy((char *)*new + start + pad, (char *)hop + end,
		       hop_len - end);

	return 0;
}

/**
 * calipso_opt_getattr - Get the security attributes from a memory block
 * @calipso: the CALIPSO option
 * @secattr: the security attributes
 *
 * Description:
 * Inspect @calipso and return the security attributes in @secattr.
 * Returns zero on success and negative values on failure.
 *
 */
static int calipso_opt_getattr(const unsigned char *calipso,
			       struct netlbl_lsm_secattr *secattr)
{
	int ret_val = -ENOMSG;
	u32 doi, len = calipso[1], cat_len = calipso[6] * 4;
	struct calipso_doi *doi_def;

	if (cat_len + 8 > len)
		return -EINVAL;

	if (calipso_cache_check(calipso + 2, calipso[1], secattr) == 0)
		return 0;

	doi = get_unaligned_be32(calipso + 2);
	rcu_read_lock();
	doi_def = calipso_doi_search(doi);
	if (!doi_def)
		goto getattr_return;

	secattr->attr.mls.lvl = calipso[7];
	secattr->flags |= NETLBL_SECATTR_MLS_LVL;

	if (cat_len) {
		ret_val = calipso_map_cat_ntoh(doi_def,
					       calipso + 10,
					       cat_len,
					       secattr);
		if (ret_val != 0) {
			netlbl_catmap_free(secattr->attr.mls.cat);
			goto getattr_return;
		}

		if (secattr->attr.mls.cat)
			secattr->flags |= NETLBL_SECATTR_MLS_CAT;
	}

	secattr->type = NETLBL_NLTYPE_CALIPSO;

getattr_return:
	rcu_read_unlock();
	return ret_val;
}

/* sock functions.
 */

/**
 * calipso_sock_getattr - Get the security attributes from a sock
 * @sk: the sock
 * @secattr: the security attributes
 *
 * Description:
 * Query @sk to see if there is a CALIPSO option attached to the sock and if
 * there is return the CALIPSO security attributes in @secattr.  This function
 * requires that @sk be locked, or privately held, but it does not do any
 * locking itself.  Returns zero on success and negative values on failure.
 *
 */
static int calipso_sock_getattr(struct sock *sk,
				struct netlbl_lsm_secattr *secattr)
{
	struct ipv6_opt_hdr *hop;
	int opt_len, len, ret_val = -ENOMSG, offset;
	unsigned char *opt;
	struct ipv6_txoptions *txopts = txopt_get(inet6_sk(sk));

	if (!txopts || !txopts->hopopt)
		goto done;

	hop = txopts->hopopt;
	opt = (unsigned char *)hop;
	opt_len = ipv6_optlen(hop);
	offset = sizeof(*hop);
	while (offset < opt_len) {
		len = calipso_tlv_len(hop, offset);
		if (len < 0) {
			ret_val = len;
			goto done;
		}
		switch (opt[offset]) {
		case IPV6_TLV_CALIPSO:
			if (len < CALIPSO_HDR_LEN)
				ret_val = -EINVAL;
			else
				ret_val = calipso_opt_getattr(&opt[offset],
							      secattr);
			goto done;
		default:
			offset += len;
			break;
		}
	}
done:
	txopt_put(txopts);
	return ret_val;
}

/**
 * calipso_sock_setattr - Add a CALIPSO option to a socket
 * @sk: the socket
 * @doi_def: the CALIPSO DOI to use
 * @secattr: the specific security attributes of the socket
 *
 * Description:
 * Set the CALIPSO option on the given socket using the DOI definition and
 * security attributes passed to the function.  This function requires
 * exclusive access to @sk, which means it either needs to be in the
 * process of being created or locked.  Returns zero on success and negative
 * values on failure.
 *
 */
static int calipso_sock_setattr(struct sock *sk,
				const struct calipso_doi *doi_def,
				const struct netlbl_lsm_secattr *secattr)
{
	int ret_val;
	struct ipv6_opt_hdr *old, *new;
	struct ipv6_txoptions *txopts = txopt_get(inet6_sk(sk));

	old = NULL;
	if (txopts)
		old = txopts->hopopt;

	new = calipso_opt_insert(old, doi_def, secattr);
	txopt_put(txopts);
	if (IS_ERR(new))
		return PTR_ERR(new);

	ret_val = calipso_opt_update(sk, new);

	kfree(new);
	return ret_val;
}

/**
 * calipso_sock_delattr - Delete the CALIPSO option from a socket
 * @sk: the socket
 *
 * Description:
 * Removes the CALIPSO option from a socket, if present.
 *
 */
static void calipso_sock_delattr(struct sock *sk)
{
	struct ipv6_opt_hdr *new_hop;
	struct ipv6_txoptions *txopts = txopt_get(inet6_sk(sk));

	if (!txopts || !txopts->hopopt)
		goto done;

	if (calipso_opt_del(txopts->hopopt, &new_hop))
		goto done;

	calipso_opt_update(sk, new_hop);
	kfree(new_hop);

done:
	txopt_put(txopts);
}

/* request sock functions.
 */

/**
 * calipso_req_setattr - Add a CALIPSO option to a connection request socket
 * @req: the connection request socket
 * @doi_def: the CALIPSO DOI to use
 * @secattr: the specific security attributes of the socket
 *
 * Description:
 * Set the CALIPSO option on the given socket using the DOI definition and
 * security attributes passed to the function.  Returns zero on success and
 * negative values on failure.
 *
 */
static int calipso_req_setattr(struct request_sock *req,
			       const struct calipso_doi *doi_def,
			       const struct netlbl_lsm_secattr *secattr)
{
	struct ipv6_txoptions *txopts;
	struct inet_request_sock *req_inet = inet_rsk(req);
	struct ipv6_opt_hdr *old, *new;
	struct sock *sk = sk_to_full_sk(req_to_sk(req));

	if (req_inet->ipv6_opt && req_inet->ipv6_opt->hopopt)
		old = req_inet->ipv6_opt->hopopt;
	else
		old = NULL;

	new = calipso_opt_insert(old, doi_def, secattr);
	if (IS_ERR(new))
		return PTR_ERR(new);

	txopts = ipv6_renew_options(sk, req_inet->ipv6_opt, IPV6_HOPOPTS, new);

	kfree(new);

	if (IS_ERR(txopts))
		return PTR_ERR(txopts);

	txopts = xchg(&req_inet->ipv6_opt, txopts);
	if (txopts) {
		atomic_sub(txopts->tot_len, &sk->sk_omem_alloc);
		txopt_put(txopts);
	}

	return 0;
}

/**
 * calipso_req_delattr - Delete the CALIPSO option from a request socket
 * @req: the request socket
 *
 * Description:
 * Removes the CALIPSO option from a request socket, if present.
 *
 */
static void calipso_req_delattr(struct request_sock *req)
{
	struct inet_request_sock *req_inet = inet_rsk(req);
	struct ipv6_opt_hdr *new;
	struct ipv6_txoptions *txopts;
	struct sock *sk = sk_to_full_sk(req_to_sk(req));

	if (!req_inet->ipv6_opt || !req_inet->ipv6_opt->hopopt)
		return;

	if (calipso_opt_del(req_inet->ipv6_opt->hopopt, &new))
		return; /* Nothing to do */

	txopts = ipv6_renew_options(sk, req_inet->ipv6_opt, IPV6_HOPOPTS, new);

	if (!IS_ERR(txopts)) {
		txopts = xchg(&req_inet->ipv6_opt, txopts);
		if (txopts) {
			atomic_sub(txopts->tot_len, &sk->sk_omem_alloc);
			txopt_put(txopts);
		}
	}
	kfree(new);
}

/* skbuff functions.
 */

/**
 * calipso_skbuff_optptr - Find the CALIPSO option in the packet
 * @skb: the packet
 *
 * Description:
 * Parse the packet's IP header looking for a CALIPSO option.  Returns a pointer
 * to the start of the CALIPSO option on success, NULL if one if not found.
 *
 */
static unsigned char *calipso_skbuff_optptr(const struct sk_buff *skb)
{
	const struct ipv6hdr *ip6_hdr = ipv6_hdr(skb);
	int offset;

	if (ip6_hdr->nexthdr != NEXTHDR_HOP)
		return NULL;

	offset = ipv6_find_tlv(skb, sizeof(*ip6_hdr), IPV6_TLV_CALIPSO);
	if (offset >= 0)
		return (unsigned char *)ip6_hdr + offset;

	return NULL;
}

/**
 * calipso_skbuff_setattr - Set the CALIPSO option on a packet
 * @skb: the packet
 * @doi_def: the CALIPSO DOI to use
 * @secattr: the security attributes
 *
 * Description:
 * Set the CALIPSO option on the given packet based on the security attributes.
 * Returns a pointer to the IP header on success and NULL on failure.
 *
 */
static int calipso_skbuff_setattr(struct sk_buff *skb,
				  const struct calipso_doi *doi_def,
				  const struct netlbl_lsm_secattr *secattr)
{
	int ret_val;
	struct ipv6hdr *ip6_hdr;
	struct ipv6_opt_hdr *hop;
	unsigned char buf[CALIPSO_MAX_BUFFER];
	int len_delta, new_end, pad, payload;
	unsigned int start, end;

	ip6_hdr = ipv6_hdr(skb);
	if (ip6_hdr->nexthdr == NEXTHDR_HOP) {
		hop = (struct ipv6_opt_hdr *)(ip6_hdr + 1);
		ret_val = calipso_opt_find(hop, &start, &end);
		if (ret_val && ret_val != -ENOENT)
			return ret_val;
	} else {
		start = 0;
		end = 0;
	}

	memset(buf, 0, sizeof(buf));
	ret_val = calipso_genopt(buf, start & 3, sizeof(buf), doi_def, secattr);
	if (ret_val < 0)
		return ret_val;

	new_end = start + ret_val;
	/* At this point new_end aligns to 4n, so (new_end & 4) pads to 8n */
	pad = ((new_end & 4) + (end & 7)) & 7;
	len_delta = new_end - (int)end + pad;
	ret_val = skb_cow(skb, skb_headroom(skb) + len_delta);
	if (ret_val < 0)
		return ret_val;

	ip6_hdr = ipv6_hdr(skb); /* Reset as skb_cow() may have moved it */

	if (len_delta) {
		if (len_delta > 0)
			skb_push(skb, len_delta);
		else
			skb_pull(skb, -len_delta);
		memmove((char *)ip6_hdr - len_delta, ip6_hdr,
			sizeof(*ip6_hdr) + start);
		skb_reset_network_header(skb);
		ip6_hdr = ipv6_hdr(skb);
		payload = ntohs(ip6_hdr->payload_len);
		ip6_hdr->payload_len = htons(payload + len_delta);
	}

	hop = (struct ipv6_opt_hdr *)(ip6_hdr + 1);
	if (start == 0) {
		struct ipv6_opt_hdr *new_hop = (struct ipv6_opt_hdr *)buf;

		new_hop->nexthdr = ip6_hdr->nexthdr;
		new_hop->hdrlen = len_delta / 8 - 1;
		ip6_hdr->nexthdr = NEXTHDR_HOP;
	} else {
		hop->hdrlen += len_delta / 8;
	}
	memcpy((char *)hop + start, buf + (start & 3), new_end - start);
	calipso_pad_write((unsigned char *)hop, new_end, pad);

	return 0;
}

/**
 * calipso_skbuff_delattr - Delete any CALIPSO options from a packet
 * @skb: the packet
 *
 * Description:
 * Removes any and all CALIPSO options from the given packet.  Returns zero on
 * success, negative values on failure.
 *
 */
static int calipso_skbuff_delattr(struct sk_buff *skb)
{
	int ret_val;
	struct ipv6hdr *ip6_hdr;
	struct ipv6_opt_hdr *old_hop;
	u32 old_hop_len, start = 0, end = 0, delta, size, pad;

	if (!calipso_skbuff_optptr(skb))
		return 0;

	/* since we are changing the packet we should make a copy */
	ret_val = skb_cow(skb, skb_headroom(skb));
	if (ret_val < 0)
		return ret_val;

	ip6_hdr = ipv6_hdr(skb);
	old_hop = (struct ipv6_opt_hdr *)(ip6_hdr + 1);
	old_hop_len = ipv6_optlen(old_hop);

	ret_val = calipso_opt_find(old_hop, &start, &end);
	if (ret_val)
		return ret_val;

	if (start == sizeof(*old_hop) && end == old_hop_len) {
		/* There's no other option in the header so we delete
		 * the whole thing. */
		delta = old_hop_len;
		size = sizeof(*ip6_hdr);
		ip6_hdr->nexthdr = old_hop->nexthdr;
	} else {
		delta = (end - start) & ~7;
		if (delta)
			old_hop->hdrlen -= delta / 8;
		pad = (end - start) & 7;
		size = sizeof(*ip6_hdr) + start + pad;
		calipso_pad_write((unsigned char *)old_hop, start, pad);
	}

	if (delta) {
		skb_pull(skb, delta);
		memmove((char *)ip6_hdr + delta, ip6_hdr, size);
		skb_reset_network_header(skb);
	}

	return 0;
}

static const struct netlbl_calipso_ops ops = {
	.doi_add          = calipso_doi_add,
	.doi_free         = calipso_doi_free,
	.doi_remove       = calipso_doi_remove,
	.doi_getdef       = calipso_doi_getdef,
	.doi_putdef       = calipso_doi_putdef,
	.doi_walk         = calipso_doi_walk,
	.sock_getattr     = calipso_sock_getattr,
	.sock_setattr     = calipso_sock_setattr,
	.sock_delattr     = calipso_sock_delattr,
	.req_setattr      = calipso_req_setattr,
	.req_delattr      = calipso_req_delattr,
	.opt_getattr      = calipso_opt_getattr,
	.skbuff_optptr    = calipso_skbuff_optptr,
	.skbuff_setattr   = calipso_skbuff_setattr,
	.skbuff_delattr   = calipso_skbuff_delattr,
	.cache_invalidate = calipso_cache_invalidate,
	.cache_add        = calipso_cache_add
};

/**
 * calipso_init - Initialize the CALIPSO module
 *
 * Description:
 * Initialize the CALIPSO module and prepare it for use.  Returns zero on
 * success and negative values on failure.
 *
 */
int __init calipso_init(void)
{
	int ret_val;

	ret_val = calipso_cache_init();
	if (!ret_val)
		netlbl_calipso_ops_register(&ops);
	return ret_val;
}

void calipso_exit(void)
{
	netlbl_calipso_ops_register(NULL);
	calipso_cache_invalidate();
	kfree(calipso_cache);
}
