Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * NetLabel Domain Hash Table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * This file manages the domain hash table that NetLabel uses to determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * which network labeling protocol to use for a given domain.  The NetLabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * system manages static and dynamic label mappings for network protocols such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * as CIPSO and RIPSO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Author: Paul Moore <paul@paul-moore.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <net/netlabel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <net/cipso_ipv4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <net/calipso.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <asm/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include "netlabel_mgmt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "netlabel_addrlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include "netlabel_calipso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include "netlabel_domainhash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include "netlabel_user.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) struct netlbl_domhsh_tbl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	struct list_head *tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	u32 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /* Domain hash table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) /* updates should be so rare that having one spinlock for the entire hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * should be okay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static DEFINE_SPINLOCK(netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define netlbl_domhsh_rcu_deref(p) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	rcu_dereference_check(p, lockdep_is_held(&netlbl_domhsh_lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static struct netlbl_domhsh_tbl __rcu *netlbl_domhsh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static struct netlbl_dom_map __rcu *netlbl_domhsh_def_ipv4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static struct netlbl_dom_map __rcu *netlbl_domhsh_def_ipv6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * Domain Hash Table Helper Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * netlbl_domhsh_free_entry - Frees a domain hash table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * @entry: the entry's RCU field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * This function is designed to be used as a callback to the call_rcu()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * function so that the memory allocated to a hash table entry can be released
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * safely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static void netlbl_domhsh_free_entry(struct rcu_head *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	struct netlbl_dom_map *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct netlbl_af4list *iter4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	struct netlbl_af4list *tmp4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct netlbl_af6list *iter6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct netlbl_af6list *tmp6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	ptr = container_of(entry, struct netlbl_dom_map, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	if (ptr->def.type == NETLBL_NLTYPE_ADDRSELECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		netlbl_af4list_foreach_safe(iter4, tmp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 					    &ptr->def.addrsel->list4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 			netlbl_af4list_remove_entry(iter4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			kfree(netlbl_domhsh_addr4_entry(iter4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		netlbl_af6list_foreach_safe(iter6, tmp6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 					    &ptr->def.addrsel->list6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			netlbl_af6list_remove_entry(iter6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			kfree(netlbl_domhsh_addr6_entry(iter6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		kfree(ptr->def.addrsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	kfree(ptr->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	kfree(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * netlbl_domhsh_hash - Hashing function for the domain hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * @key: the domain name to hash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * This is the hashing function for the domain hash table, it returns the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * correct bucket number for the domain.  The caller is responsible for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * ensuring that the hash table is protected with either a RCU read lock or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * hash table lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static u32 netlbl_domhsh_hash(const char *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	u32 iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	/* This is taken (with slight modification) from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	 * security/selinux/ss/symtab.c:symhash() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	for (iter = 0, val = 0, len = strlen(key); iter < len; iter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		val = (val << 4 | (val >> (8 * sizeof(u32) - 4))) ^ key[iter];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	return val & (netlbl_domhsh_rcu_deref(netlbl_domhsh)->size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static bool netlbl_family_match(u16 f1, u16 f2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	return (f1 == f2) || (f1 == AF_UNSPEC) || (f2 == AF_UNSPEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * netlbl_domhsh_search - Search for a domain entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * @domain: the domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * @family: the address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * Searches the domain hash table and returns a pointer to the hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * entry if found, otherwise NULL is returned.  @family may be %AF_UNSPEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * which matches any address family entries.  The caller is responsible for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * ensuring that the hash table is protected with either a RCU read lock or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * hash table lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 						   u16 family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	u32 bkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	struct list_head *bkt_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	struct netlbl_dom_map *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	if (domain != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		bkt = netlbl_domhsh_hash(domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		bkt_list = &netlbl_domhsh_rcu_deref(netlbl_domhsh)->tbl[bkt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		list_for_each_entry_rcu(iter, bkt_list, list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 					lockdep_is_held(&netlbl_domhsh_lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			if (iter->valid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			    netlbl_family_match(iter->family, family) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			    strcmp(iter->domain, domain) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 				return iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  * netlbl_domhsh_search_def - Search for a domain entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * @domain: the domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  * @family: the address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  * Searches the domain hash table and returns a pointer to the hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  * entry if an exact match is found, if an exact match is not present in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * hash table then the default entry is returned if valid otherwise NULL is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  * returned.  @family may be %AF_UNSPEC which matches any address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * entries.  The caller is responsible ensuring that the hash table is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  * protected with either a RCU read lock or the hash table lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 						       u16 family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	struct netlbl_dom_map *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	entry = netlbl_domhsh_search(domain, family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	if (entry != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	if (family == AF_INET || family == AF_UNSPEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		entry = netlbl_domhsh_rcu_deref(netlbl_domhsh_def_ipv4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		if (entry != NULL && entry->valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	if (family == AF_INET6 || family == AF_UNSPEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		entry = netlbl_domhsh_rcu_deref(netlbl_domhsh_def_ipv6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		if (entry != NULL && entry->valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * netlbl_domhsh_audit_add - Generate an audit entry for an add event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  * @entry: the entry being added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  * @addr4: the IPv4 address information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  * @addr6: the IPv6 address information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  * @result: the result code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * Generate an audit record for adding a new NetLabel/LSM mapping entry with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  * the given information.  Caller is responsible for holding the necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  * locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 				    struct netlbl_af4list *addr4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 				    struct netlbl_af6list *addr6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 				    int result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 				    struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	struct audit_buffer *audit_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	struct cipso_v4_doi *cipsov4 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	struct calipso_doi *calipso = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (audit_buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		audit_log_format(audit_buf, " nlbl_domain=%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 				 entry->domain ? entry->domain : "(default)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		if (addr4 != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			struct netlbl_domaddr4_map *map4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			map4 = netlbl_domhsh_addr4_entry(addr4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			type = map4->def.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			cipsov4 = map4->def.cipso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			netlbl_af4list_audit_addr(audit_buf, 0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 						  addr4->addr, addr4->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		} else if (addr6 != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			struct netlbl_domaddr6_map *map6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			map6 = netlbl_domhsh_addr6_entry(addr6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			type = map6->def.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			calipso = map6->def.calipso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			netlbl_af6list_audit_addr(audit_buf, 0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 						  &addr6->addr, &addr6->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			type = entry->def.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			cipsov4 = entry->def.cipso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			calipso = entry->def.calipso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			audit_log_format(audit_buf, " nlbl_protocol=unlbl");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		case NETLBL_NLTYPE_CIPSOV4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			BUG_ON(cipsov4 == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			audit_log_format(audit_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 					 " nlbl_protocol=cipsov4 cipso_doi=%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 					 cipsov4->doi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		case NETLBL_NLTYPE_CALIPSO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			BUG_ON(calipso == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			audit_log_format(audit_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 					 " nlbl_protocol=calipso calipso_doi=%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 					 calipso->doi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		audit_log_format(audit_buf, " res=%u", result == 0 ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		audit_log_end(audit_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)  * netlbl_domhsh_validate - Validate a new domain mapping entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  * @entry: the entry to validate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  * This function validates the new domain mapping entry to ensure that it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  * a valid entry.  Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	struct netlbl_af4list *iter4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	struct netlbl_domaddr4_map *map4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	struct netlbl_af6list *iter6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	struct netlbl_domaddr6_map *map6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	if (entry == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	if (entry->family != AF_INET && entry->family != AF_INET6 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	    (entry->family != AF_UNSPEC ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	     entry->def.type != NETLBL_NLTYPE_UNLABELED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	switch (entry->def.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		if (entry->def.cipso != NULL || entry->def.calipso != NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		    entry->def.addrsel != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	case NETLBL_NLTYPE_CIPSOV4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		if (entry->family != AF_INET ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		    entry->def.cipso == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	case NETLBL_NLTYPE_CALIPSO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		if (entry->family != AF_INET6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		    entry->def.calipso == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	case NETLBL_NLTYPE_ADDRSELECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		netlbl_af4list_foreach(iter4, &entry->def.addrsel->list4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			map4 = netlbl_domhsh_addr4_entry(iter4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 			switch (map4->def.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 				if (map4->def.cipso != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 			case NETLBL_NLTYPE_CIPSOV4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 				if (map4->def.cipso == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		netlbl_af6list_foreach(iter6, &entry->def.addrsel->list6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 			map6 = netlbl_domhsh_addr6_entry(iter6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			switch (map6->def.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 				if (map6->def.calipso != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 			case NETLBL_NLTYPE_CALIPSO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 				if (map6->def.calipso == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)  * Domain Hash Table Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)  * netlbl_domhsh_init - Init for the domain hash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)  * @size: the number of bits to use for the hash buckets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  * Initializes the domain hash table, should be called only by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  * netlbl_user_init() during initialization.  Returns zero on success, non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  * values on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int __init netlbl_domhsh_init(u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	u32 iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	struct netlbl_domhsh_tbl *hsh_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	if (size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	hsh_tbl = kmalloc(sizeof(*hsh_tbl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (hsh_tbl == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	hsh_tbl->size = 1 << size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	hsh_tbl->tbl = kcalloc(hsh_tbl->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			       sizeof(struct list_head),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			       GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	if (hsh_tbl->tbl == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		kfree(hsh_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	for (iter = 0; iter < hsh_tbl->size; iter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		INIT_LIST_HEAD(&hsh_tbl->tbl[iter]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	spin_lock(&netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	rcu_assign_pointer(netlbl_domhsh, hsh_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	spin_unlock(&netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  * netlbl_domhsh_add - Adds a entry to the domain hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  * @entry: the entry to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  * Adds a new entry to the domain hash table and handles any updates to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  * lower level protocol handler (i.e. CIPSO).  @entry->family may be set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  * %AF_UNSPEC which will add an entry that matches all address families.  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)  * is only useful for the unlabelled type and will only succeed if there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)  * existing entry for any address family with the same domain.  Returns zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)  * on success, negative on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int netlbl_domhsh_add(struct netlbl_dom_map *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		      struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	int ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	struct netlbl_dom_map *entry_old, *entry_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	struct netlbl_af4list *iter4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	struct netlbl_af4list *tmp4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	struct netlbl_af6list *iter6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	struct netlbl_af6list *tmp6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	ret_val = netlbl_domhsh_validate(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	/* XXX - we can remove this RCU read lock as the spinlock protects the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	 *       entire function, but before we do we need to fixup the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	 *       netlbl_af[4,6]list RCU functions to do "the right thing" with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	 *       respect to rcu_dereference() when only a spinlock is held. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	spin_lock(&netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	if (entry->domain != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		entry_old = netlbl_domhsh_search(entry->domain, entry->family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		entry_old = netlbl_domhsh_search_def(entry->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 						     entry->family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	if (entry_old == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		entry->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if (entry->domain != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			u32 bkt = netlbl_domhsh_hash(entry->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 			list_add_tail_rcu(&entry->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 				    &rcu_dereference(netlbl_domhsh)->tbl[bkt]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			INIT_LIST_HEAD(&entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 			switch (entry->family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 			case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 				rcu_assign_pointer(netlbl_domhsh_def_ipv4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 						   entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 				rcu_assign_pointer(netlbl_domhsh_def_ipv6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 						   entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			case AF_UNSPEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 				if (entry->def.type !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 				    NETLBL_NLTYPE_UNLABELED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 					ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 					goto add_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 				entry_b = kzalloc(sizeof(*entry_b), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 				if (entry_b == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 					ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 					goto add_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 				entry_b->family = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 				entry_b->def.type = NETLBL_NLTYPE_UNLABELED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 				entry_b->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 				entry->family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 				rcu_assign_pointer(netlbl_domhsh_def_ipv4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 						   entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 				rcu_assign_pointer(netlbl_domhsh_def_ipv6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 						   entry_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 				/* Already checked in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 				 * netlbl_domhsh_validate(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 				ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 				goto add_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		if (entry->def.type == NETLBL_NLTYPE_ADDRSELECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			netlbl_af4list_foreach_rcu(iter4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 						   &entry->def.addrsel->list4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 				netlbl_domhsh_audit_add(entry, iter4, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 							ret_val, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			netlbl_af6list_foreach_rcu(iter6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 						   &entry->def.addrsel->list6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 				netlbl_domhsh_audit_add(entry, NULL, iter6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 							ret_val, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			netlbl_domhsh_audit_add(entry, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 						ret_val, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	} else if (entry_old->def.type == NETLBL_NLTYPE_ADDRSELECT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		   entry->def.type == NETLBL_NLTYPE_ADDRSELECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		struct list_head *old_list4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		struct list_head *old_list6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		old_list4 = &entry_old->def.addrsel->list4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		old_list6 = &entry_old->def.addrsel->list6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		/* we only allow the addition of address selectors if all of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		 * the selectors do not exist in the existing domain map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		netlbl_af4list_foreach_rcu(iter4, &entry->def.addrsel->list4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 			if (netlbl_af4list_search_exact(iter4->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 							iter4->mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 							old_list4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 				ret_val = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 				goto add_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		netlbl_af6list_foreach_rcu(iter6, &entry->def.addrsel->list6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			if (netlbl_af6list_search_exact(&iter6->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 							&iter6->mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 							old_list6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 				ret_val = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 				goto add_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		netlbl_af4list_foreach_safe(iter4, tmp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 					    &entry->def.addrsel->list4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 			netlbl_af4list_remove_entry(iter4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 			iter4->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			ret_val = netlbl_af4list_add(iter4, old_list4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 			netlbl_domhsh_audit_add(entry_old, iter4, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 						ret_val, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 				goto add_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		netlbl_af6list_foreach_safe(iter6, tmp6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 					    &entry->def.addrsel->list6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 			netlbl_af6list_remove_entry(iter6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 			iter6->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			ret_val = netlbl_af6list_add(iter6, old_list6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			netlbl_domhsh_audit_add(entry_old, NULL, iter6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 						ret_val, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 				goto add_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		/* cleanup the new entry since we've moved everything over */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		netlbl_domhsh_free_entry(&entry->rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) add_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	spin_unlock(&netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)  * netlbl_domhsh_add_default - Adds the default entry to the domain hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)  * @entry: the entry to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)  * Adds a new default entry to the domain hash table and handles any updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)  * to the lower level protocol handler (i.e. CIPSO).  Returns zero on success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)  * negative on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			      struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	return netlbl_domhsh_add(entry, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)  * netlbl_domhsh_remove_entry - Removes a given entry from the domain table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)  * @entry: the entry to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)  * Removes an entry from the domain hash table and handles any updates to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)  * lower level protocol handler (i.e. CIPSO).  Caller is responsible for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)  * ensuring that the RCU read lock is held.  Returns zero on success, negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)  * on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 			       struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	int ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	struct audit_buffer *audit_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	struct netlbl_af4list *iter4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	struct netlbl_domaddr4_map *map4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	struct netlbl_af6list *iter6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	struct netlbl_domaddr6_map *map6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	if (entry == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	spin_lock(&netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	if (entry->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		entry->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		if (entry == rcu_dereference(netlbl_domhsh_def_ipv4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 			RCU_INIT_POINTER(netlbl_domhsh_def_ipv4, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		else if (entry == rcu_dereference(netlbl_domhsh_def_ipv6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 			RCU_INIT_POINTER(netlbl_domhsh_def_ipv6, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 			list_del_rcu(&entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	spin_unlock(&netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	if (ret_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	if (audit_buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		audit_log_format(audit_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 				 " nlbl_domain=%s res=1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 				 entry->domain ? entry->domain : "(default)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		audit_log_end(audit_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	switch (entry->def.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	case NETLBL_NLTYPE_ADDRSELECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		netlbl_af4list_foreach_rcu(iter4, &entry->def.addrsel->list4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 			map4 = netlbl_domhsh_addr4_entry(iter4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 			cipso_v4_doi_putdef(map4->def.cipso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		netlbl_af6list_foreach_rcu(iter6, &entry->def.addrsel->list6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 			map6 = netlbl_domhsh_addr6_entry(iter6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 			calipso_doi_putdef(map6->def.calipso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	case NETLBL_NLTYPE_CIPSOV4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		cipso_v4_doi_putdef(entry->def.cipso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	case NETLBL_NLTYPE_CALIPSO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		calipso_doi_putdef(entry->def.calipso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)  * netlbl_domhsh_remove_af4 - Removes an address selector entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)  * @domain: the domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)  * @addr: IPv4 address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)  * @mask: IPv4 address mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)  * Removes an individual address selector from a domain mapping and potentially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)  * the entire mapping if it is empty.  Returns zero on success, negative values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)  * on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) int netlbl_domhsh_remove_af4(const char *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 			     const struct in_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 			     const struct in_addr *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 			     struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	struct netlbl_dom_map *entry_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	struct netlbl_af4list *entry_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	struct netlbl_af4list *iter4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	struct netlbl_af6list *iter6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	struct netlbl_domaddr4_map *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	if (domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		entry_map = netlbl_domhsh_search(domain, AF_INET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		entry_map = netlbl_domhsh_search_def(domain, AF_INET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	if (entry_map == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	    entry_map->def.type != NETLBL_NLTYPE_ADDRSELECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		goto remove_af4_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	spin_lock(&netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	entry_addr = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 					   &entry_map->def.addrsel->list4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	spin_unlock(&netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	if (entry_addr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		goto remove_af4_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	netlbl_af4list_foreach_rcu(iter4, &entry_map->def.addrsel->list4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		goto remove_af4_single_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	netlbl_af6list_foreach_rcu(iter6, &entry_map->def.addrsel->list6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		goto remove_af4_single_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	/* the domain mapping is empty so remove it from the mapping table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	netlbl_domhsh_remove_entry(entry_map, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) remove_af4_single_addr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	/* yick, we can't use call_rcu here because we don't have a rcu head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	 * pointer but hopefully this should be a rare case so the pause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	 * shouldn't be a problem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	entry = netlbl_domhsh_addr4_entry(entry_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	cipso_v4_doi_putdef(entry->def.cipso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) remove_af4_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)  * netlbl_domhsh_remove_af6 - Removes an address selector entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)  * @domain: the domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)  * @addr: IPv6 address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)  * @mask: IPv6 address mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)  * Removes an individual address selector from a domain mapping and potentially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)  * the entire mapping if it is empty.  Returns zero on success, negative values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)  * on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) int netlbl_domhsh_remove_af6(const char *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 			     const struct in6_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 			     const struct in6_addr *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 			     struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	struct netlbl_dom_map *entry_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	struct netlbl_af6list *entry_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	struct netlbl_af4list *iter4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	struct netlbl_af6list *iter6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	struct netlbl_domaddr6_map *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	if (domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		entry_map = netlbl_domhsh_search(domain, AF_INET6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		entry_map = netlbl_domhsh_search_def(domain, AF_INET6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	if (entry_map == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	    entry_map->def.type != NETLBL_NLTYPE_ADDRSELECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		goto remove_af6_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	spin_lock(&netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	entry_addr = netlbl_af6list_remove(addr, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 					   &entry_map->def.addrsel->list6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	spin_unlock(&netlbl_domhsh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	if (entry_addr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 		goto remove_af6_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	netlbl_af4list_foreach_rcu(iter4, &entry_map->def.addrsel->list4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		goto remove_af6_single_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	netlbl_af6list_foreach_rcu(iter6, &entry_map->def.addrsel->list6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 		goto remove_af6_single_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	/* the domain mapping is empty so remove it from the mapping table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	netlbl_domhsh_remove_entry(entry_map, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) remove_af6_single_addr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	/* yick, we can't use call_rcu here because we don't have a rcu head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	 * pointer but hopefully this should be a rare case so the pause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	 * shouldn't be a problem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	entry = netlbl_domhsh_addr6_entry(entry_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	calipso_doi_putdef(entry->def.calipso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) remove_af6_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)  * netlbl_domhsh_remove - Removes an entry from the domain hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)  * @domain: the domain to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)  * @family: address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)  * Removes an entry from the domain hash table and handles any updates to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)  * lower level protocol handler (i.e. CIPSO).  @family may be %AF_UNSPEC which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)  * removes all address family entries.  Returns zero on success, negative on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)  * failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) int netlbl_domhsh_remove(const char *domain, u16 family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 			 struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	int ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	struct netlbl_dom_map *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	if (family == AF_INET || family == AF_UNSPEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		if (domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 			entry = netlbl_domhsh_search(domain, AF_INET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 			entry = netlbl_domhsh_search_def(domain, AF_INET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 		ret_val = netlbl_domhsh_remove_entry(entry, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 		if (ret_val && ret_val != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	if (family == AF_INET6 || family == AF_UNSPEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		int ret_val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 		if (domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 			entry = netlbl_domhsh_search(domain, AF_INET6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 			entry = netlbl_domhsh_search_def(domain, AF_INET6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 		ret_val2 = netlbl_domhsh_remove_entry(entry, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 		if (ret_val2 != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 			ret_val = ret_val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)  * netlbl_domhsh_remove_default - Removes the default entry from the table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)  * @family: address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)  * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)  * Removes/resets the default entry corresponding to @family from the domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)  * hash table and handles any updates to the lower level protocol handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)  * (i.e. CIPSO).  @family may be %AF_UNSPEC which removes all address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)  * entries.  Returns zero on success, negative on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) int netlbl_domhsh_remove_default(u16 family, struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	return netlbl_domhsh_remove(NULL, family, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)  * netlbl_domhsh_getentry - Get an entry from the domain hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)  * @domain: the domain name to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)  * @family: address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)  * Look through the domain hash table searching for an entry to match @domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)  * with address family @family, return a pointer to a copy of the entry or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)  * NULL.  The caller is responsible for ensuring that rcu_read_[un]lock() is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)  * called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain, u16 family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	if (family == AF_UNSPEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	return netlbl_domhsh_search_def(domain, family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)  * netlbl_domhsh_getentry_af4 - Get an entry from the domain hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)  * @domain: the domain name to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)  * @addr: the IP address to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)  * Look through the domain hash table searching for an entry to match @domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)  * and @addr, return a pointer to a copy of the entry or NULL.  The caller is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)  * responsible for ensuring that rcu_read_[un]lock() is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct netlbl_dommap_def *netlbl_domhsh_getentry_af4(const char *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 						     __be32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 	struct netlbl_dom_map *dom_iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	struct netlbl_af4list *addr_iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	dom_iter = netlbl_domhsh_search_def(domain, AF_INET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	if (dom_iter == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 	if (dom_iter->def.type != NETLBL_NLTYPE_ADDRSELECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 		return &dom_iter->def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 	addr_iter = netlbl_af4list_search(addr, &dom_iter->def.addrsel->list4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 	if (addr_iter == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 	return &(netlbl_domhsh_addr4_entry(addr_iter)->def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)  * netlbl_domhsh_getentry_af6 - Get an entry from the domain hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)  * @domain: the domain name to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)  * @addr: the IP address to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)  * Look through the domain hash table searching for an entry to match @domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)  * and @addr, return a pointer to a copy of the entry or NULL.  The caller is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)  * responsible for ensuring that rcu_read_[un]lock() is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct netlbl_dommap_def *netlbl_domhsh_getentry_af6(const char *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 						   const struct in6_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 	struct netlbl_dom_map *dom_iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 	struct netlbl_af6list *addr_iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 	dom_iter = netlbl_domhsh_search_def(domain, AF_INET6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 	if (dom_iter == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 	if (dom_iter->def.type != NETLBL_NLTYPE_ADDRSELECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 		return &dom_iter->def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 	addr_iter = netlbl_af6list_search(addr, &dom_iter->def.addrsel->list6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	if (addr_iter == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 	return &(netlbl_domhsh_addr6_entry(addr_iter)->def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)  * netlbl_domhsh_walk - Iterate through the domain mapping hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)  * @skip_bkt: the number of buckets to skip at the start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)  * @skip_chain: the number of entries to skip in the first iterated bucket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)  * @callback: callback for each entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)  * @cb_arg: argument for the callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)  * Interate over the domain mapping hash table, skipping the first @skip_bkt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)  * buckets and @skip_chain entries.  For each entry in the table call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)  * @callback, if @callback returns a negative value stop 'walking' through the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)  * table and return.  Updates the values in @skip_bkt and @skip_chain on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)  * return.  Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) int netlbl_domhsh_walk(u32 *skip_bkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 		     u32 *skip_chain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 		     int (*callback) (struct netlbl_dom_map *entry, void *arg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 		     void *cb_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	int ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 	u32 iter_bkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 	struct list_head *iter_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 	struct netlbl_dom_map *iter_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 	u32 chain_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) 	for (iter_bkt = *skip_bkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 	     iter_bkt < rcu_dereference(netlbl_domhsh)->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) 	     iter_bkt++, chain_cnt = 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 		iter_list = &rcu_dereference(netlbl_domhsh)->tbl[iter_bkt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 		list_for_each_entry_rcu(iter_entry, iter_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 			if (iter_entry->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) 				if (chain_cnt++ < *skip_chain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) 				ret_val = callback(iter_entry, cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) 				if (ret_val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) 					chain_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) 					goto walk_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) walk_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) 	*skip_bkt = iter_bkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) 	*skip_chain = chain_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) 	return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }