31 #include <linux/types.h>
33 #include <linux/list.h>
34 #include <linux/slab.h>
37 #include <linux/in6.h>
39 #include <linux/ipv6.h>
46 #define SEL_NETNODE_HASH_SIZE 256
47 #define SEL_NETNODE_HASH_BKT_LIMIT 16
80 static unsigned int sel_netnode_hashfn_ipv4(
__be32 addr)
96 static unsigned int sel_netnode_hashfn_ipv6(
const struct in6_addr *addr)
121 idx = sel_netnode_hashfn_ipv4(*(
__be32 *)addr);
124 idx = sel_netnode_hashfn_ipv6(addr);
131 list_for_each_entry_rcu(node, &sel_netnode_hash[idx].
list, list)
132 if (node->
nsec.family == family)
139 if (ipv6_addr_equal(&node->
nsec.addr.ipv6,
156 static void sel_netnode_insert(
struct sel_netnode *node)
160 switch (node->
nsec.family) {
162 idx = sel_netnode_hashfn_ipv4(node->
nsec.addr.ipv4);
165 idx = sel_netnode_hashfn_ipv6(&node->
nsec.addr.ipv6);
173 list_add_rcu(&node->
list, &sel_netnode_hash[idx].list);
178 lockdep_is_held(&sel_netnode_lock)),
180 list_del_rcu(&tail->
list);
183 sel_netnode_hash[
idx].size++;
199 static int sel_netnode_sid_slow(
void *addr,
u16 family,
u32 *
sid)
205 spin_lock_bh(&sel_netnode_lock);
206 node = sel_netnode_find(addr, family);
208 *sid = node->
nsec.sid;
209 spin_unlock_bh(&sel_netnode_lock);
218 addr,
sizeof(
struct in_addr), sid);
219 new->nsec.addr.ipv4 = *(
__be32 *)addr;
223 addr,
sizeof(
struct in6_addr), sid);
224 new->nsec.addr.ipv6 = *(
struct in6_addr *)addr;
232 new->nsec.family =
family;
233 new->nsec.sid = *
sid;
234 sel_netnode_insert(
new);
237 spin_unlock_bh(&sel_netnode_lock);
240 "SELinux: failure in sel_netnode_sid_slow(),"
241 " unable to determine network node label\n");
266 node = sel_netnode_find(addr, family);
268 *sid = node->
nsec.sid;
274 return sel_netnode_sid_slow(addr, family, sid);
284 static void sel_netnode_flush(
void)
289 spin_lock_bh(&sel_netnode_lock);
292 &sel_netnode_hash[idx].list, list) {
293 list_del_rcu(&node->
list);
296 sel_netnode_hash[
idx].size = 0;
298 spin_unlock_bh(&sel_netnode_lock);
301 static int sel_netnode_avc_callback(
u32 event)
310 static __init int sel_netnode_init(
void)
319 INIT_LIST_HEAD(&sel_netnode_hash[iter].list);
320 sel_netnode_hash[iter].size = 0;
325 panic(
"avc_add_callback() failed, error %d\n", ret);