linux/net/netlabel/netlabel_domainhash.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * NetLabel Domain Hash Table
 *
 * This file manages the domain hash table that NetLabel uses to determine
 * which network labeling protocol to use for a given domain.  The NetLabel
 * system manages static and dynamic label mappings for network protocols such
 * as CIPSO and RIPSO.
 *
 * Author: Paul Moore <[email protected]>
 */

/*
 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
 */

#include <linux/types.h>
#include <linux/rculist.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/audit.h>
#include <linux/slab.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
#include <net/calipso.h>
#include <asm/bug.h>

#include "netlabel_mgmt.h"
#include "netlabel_addrlist.h"
#include "netlabel_calipso.h"
#include "netlabel_domainhash.h"
#include "netlabel_user.h"

struct netlbl_domhsh_tbl {};

/* Domain hash table */
/* updates should be so rare that having one spinlock for the entire hash table
 * should be okay */
static DEFINE_SPINLOCK(netlbl_domhsh_lock);
#define netlbl_domhsh_rcu_deref(p)
static struct netlbl_domhsh_tbl __rcu *netlbl_domhsh;
static struct netlbl_dom_map __rcu *netlbl_domhsh_def_ipv4;
static struct netlbl_dom_map __rcu *netlbl_domhsh_def_ipv6;

/*
 * Domain Hash Table Helper Functions
 */

/**
 * netlbl_domhsh_free_entry - Frees a domain hash table entry
 * @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 a hash table entry can be released
 * safely.
 *
 */
static void netlbl_domhsh_free_entry(struct rcu_head *entry)
{}

/**
 * netlbl_domhsh_hash - Hashing function for the domain hash table
 * @key: the domain name to hash
 *
 * Description:
 * This is the hashing function for the domain hash table, it returns the
 * correct bucket number for the domain.  The caller is responsible for
 * ensuring that the hash table is protected with either a RCU read lock or the
 * hash table lock.
 *
 */
static u32 netlbl_domhsh_hash(const char *key)
{}

static bool netlbl_family_match(u16 f1, u16 f2)
{}

/**
 * netlbl_domhsh_search - Search for a domain entry
 * @domain: the domain
 * @family: the address family
 *
 * Description:
 * Searches the domain hash table and returns a pointer to the hash table
 * entry if found, otherwise NULL is returned.  @family may be %AF_UNSPEC
 * which matches any address family entries.  The caller is responsible for
 * ensuring that the hash table is protected with either a RCU read lock or the
 * hash table lock.
 *
 */
static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain,
						   u16 family)
{}

/**
 * netlbl_domhsh_search_def - Search for a domain entry
 * @domain: the domain
 * @family: the address family
 *
 * Description:
 * Searches the domain hash table and returns a pointer to the hash table
 * entry if an exact match is found, if an exact match is not present in the
 * hash table then the default entry is returned if valid otherwise NULL is
 * returned.  @family may be %AF_UNSPEC which matches any address family
 * entries.  The caller is responsible ensuring that the hash table is
 * protected with either a RCU read lock or the hash table lock.
 *
 */
static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain,
						       u16 family)
{}

/**
 * netlbl_domhsh_audit_add - Generate an audit entry for an add event
 * @entry: the entry being added
 * @addr4: the IPv4 address information
 * @addr6: the IPv6 address information
 * @result: the result code
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Generate an audit record for adding a new NetLabel/LSM mapping entry with
 * the given information.  Caller is responsible for holding the necessary
 * locks.
 *
 */
static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
				    struct netlbl_af4list *addr4,
				    struct netlbl_af6list *addr6,
				    int result,
				    struct netlbl_audit *audit_info)
{}

/**
 * netlbl_domhsh_validate - Validate a new domain mapping entry
 * @entry: the entry to validate
 *
 * This function validates the new domain mapping entry to ensure that it is
 * a valid entry.  Returns zero on success, negative values on failure.
 *
 */
static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
{}

/*
 * Domain Hash Table Functions
 */

/**
 * netlbl_domhsh_init - Init for the domain hash
 * @size: the number of bits to use for the hash buckets
 *
 * Description:
 * Initializes the domain hash table, should be called only by
 * netlbl_user_init() during initialization.  Returns zero on success, non-zero
 * values on error.
 *
 */
int __init netlbl_domhsh_init(u32 size)
{}

/**
 * netlbl_domhsh_add - Adds a entry to the domain hash table
 * @entry: the entry to add
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Adds a new entry to the domain hash table and handles any updates to the
 * lower level protocol handler (i.e. CIPSO).  @entry->family may be set to
 * %AF_UNSPEC which will add an entry that matches all address families.  This
 * is only useful for the unlabelled type and will only succeed if there is no
 * existing entry for any address family with the same domain.  Returns zero
 * on success, negative on failure.
 *
 */
int netlbl_domhsh_add(struct netlbl_dom_map *entry,
		      struct netlbl_audit *audit_info)
{}

/**
 * netlbl_domhsh_add_default - Adds the default entry to the domain hash table
 * @entry: the entry to add
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Adds a new default entry to the domain hash table and handles any updates
 * to the lower level protocol handler (i.e. CIPSO).  Returns zero on success,
 * negative on failure.
 *
 */
int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
			      struct netlbl_audit *audit_info)
{}

/**
 * netlbl_domhsh_remove_entry - Removes a given entry from the domain table
 * @entry: the entry to remove
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Removes an entry from the domain hash table and handles any updates to the
 * lower level protocol handler (i.e. CIPSO).  Caller is responsible for
 * ensuring that the RCU read lock is held.  Returns zero on success, negative
 * on failure.
 *
 */
int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
			       struct netlbl_audit *audit_info)
{}

/**
 * netlbl_domhsh_remove_af4 - Removes an address selector entry
 * @domain: the domain
 * @addr: IPv4 address
 * @mask: IPv4 address mask
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Removes an individual address selector from a domain mapping and potentially
 * the entire mapping if it is empty.  Returns zero on success, negative values
 * on failure.
 *
 */
int netlbl_domhsh_remove_af4(const char *domain,
			     const struct in_addr *addr,
			     const struct in_addr *mask,
			     struct netlbl_audit *audit_info)
{}

#if IS_ENABLED(CONFIG_IPV6)
/**
 * netlbl_domhsh_remove_af6 - Removes an address selector entry
 * @domain: the domain
 * @addr: IPv6 address
 * @mask: IPv6 address mask
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Removes an individual address selector from a domain mapping and potentially
 * the entire mapping if it is empty.  Returns zero on success, negative values
 * on failure.
 *
 */
int netlbl_domhsh_remove_af6(const char *domain,
			     const struct in6_addr *addr,
			     const struct in6_addr *mask,
			     struct netlbl_audit *audit_info)
{}
#endif /* IPv6 */

/**
 * netlbl_domhsh_remove - Removes an entry from the domain hash table
 * @domain: the domain to remove
 * @family: address family
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Removes an entry from the domain hash table and handles any updates to the
 * lower level protocol handler (i.e. CIPSO).  @family may be %AF_UNSPEC which
 * removes all address family entries.  Returns zero on success, negative on
 * failure.
 *
 */
int netlbl_domhsh_remove(const char *domain, u16 family,
			 struct netlbl_audit *audit_info)
{}

/**
 * netlbl_domhsh_remove_default - Removes the default entry from the table
 * @family: address family
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Removes/resets the default entry corresponding to @family from the domain
 * hash table and handles any updates to the lower level protocol handler
 * (i.e. CIPSO).  @family may be %AF_UNSPEC which removes all address family
 * entries.  Returns zero on success, negative on failure.
 *
 */
int netlbl_domhsh_remove_default(u16 family, struct netlbl_audit *audit_info)
{}

/**
 * netlbl_domhsh_getentry - Get an entry from the domain hash table
 * @domain: the domain name to search for
 * @family: address family
 *
 * Description:
 * Look through the domain hash table searching for an entry to match @domain,
 * with address family @family, return a pointer to a copy of the entry or
 * NULL.  The caller is responsible for ensuring that rcu_read_[un]lock() is
 * called.
 *
 */
struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain, u16 family)
{}

/**
 * netlbl_domhsh_getentry_af4 - Get an entry from the domain hash table
 * @domain: the domain name to search for
 * @addr: the IP address to search for
 *
 * Description:
 * Look through the domain hash table searching for an entry to match @domain
 * and @addr, return a pointer to a copy of the entry or NULL.  The caller is
 * responsible for ensuring that rcu_read_[un]lock() is called.
 *
 */
struct netlbl_dommap_def *netlbl_domhsh_getentry_af4(const char *domain,
						     __be32 addr)
{}

#if IS_ENABLED(CONFIG_IPV6)
/**
 * netlbl_domhsh_getentry_af6 - Get an entry from the domain hash table
 * @domain: the domain name to search for
 * @addr: the IP address to search for
 *
 * Description:
 * Look through the domain hash table searching for an entry to match @domain
 * and @addr, return a pointer to a copy of the entry or NULL.  The caller is
 * responsible for ensuring that rcu_read_[un]lock() is called.
 *
 */
struct netlbl_dommap_def *netlbl_domhsh_getentry_af6(const char *domain,
						   const struct in6_addr *addr)
{}
#endif /* IPv6 */

/**
 * netlbl_domhsh_walk - Iterate through the domain mapping hash table
 * @skip_bkt: the number of buckets to skip at the start
 * @skip_chain: the number of entries to skip in the first iterated bucket
 * @callback: callback for each entry
 * @cb_arg: argument for the callback function
 *
 * Description:
 * Iterate over the domain mapping hash table, skipping the first @skip_bkt
 * buckets and @skip_chain entries.  For each entry in the table call
 * @callback, if @callback returns a negative value stop 'walking' through the
 * table and return.  Updates the values in @skip_bkt and @skip_chain on
 * return.  Returns zero on success, negative values on failure.
 *
 */
int netlbl_domhsh_walk(u32 *skip_bkt,
		     u32 *skip_chain,
		     int (*callback) (struct netlbl_dom_map *entry, void *arg),
		     void *cb_arg)
{}