32 #include <linux/types.h>
36 #include <linux/string.h>
37 #include <linux/audit.h>
38 #include <linux/slab.h>
57 #define netlbl_domhsh_rcu_deref(p) \
58 rcu_dereference_check(p, lockdep_is_held(&netlbl_domhsh_lock))
81 #if IS_ENABLED(CONFIG_IPV6)
93 #if IS_ENABLED(CONFIG_IPV6)
94 netlbl_af6list_foreach_safe(iter6, tmp6,
96 netlbl_af6list_remove_entry(iter6);
116 static u32 netlbl_domhsh_hash(
const char *
key)
125 for (iter = 0, val = 0, len =
strlen(key); iter < len; iter++)
126 val = (val << 4 | (val >> (8 *
sizeof(
u32) - 4))) ^ key[iter];
147 if (domain !=
NULL) {
148 bkt = netlbl_domhsh_hash(domain);
150 list_for_each_entry_rcu(iter, bkt_list,
list)
175 entry = netlbl_domhsh_search(domain);
178 if (entry != NULL && !entry->
valid)
210 if (audit_buf != NULL) {
218 netlbl_af4list_audit_addr(audit_buf, 0, NULL,
220 #if IS_ENABLED(CONFIG_IPV6)
221 }
else if (addr6 != NULL) {
225 netlbl_af6list_audit_addr(audit_buf, 0, NULL,
239 " nlbl_protocol=cipsov4 cipso_doi=%u",
274 hsh_tbl->
tbl = kcalloc(hsh_tbl->
size,
277 if (hsh_tbl->
tbl == NULL) {
281 for (iter = 0; iter < hsh_tbl->
size; iter++)
282 INIT_LIST_HEAD(&hsh_tbl->
tbl[iter]);
284 spin_lock(&netlbl_domhsh_lock);
286 spin_unlock(&netlbl_domhsh_lock);
309 #if IS_ENABLED(CONFIG_IPV6)
319 spin_lock(&netlbl_domhsh_lock);
320 if (entry->
domain != NULL)
321 entry_old = netlbl_domhsh_search(entry->
domain);
323 entry_old = netlbl_domhsh_search_def(entry->
domain);
324 if (entry_old == NULL) {
327 if (entry->
domain != NULL) {
328 u32 bkt = netlbl_domhsh_hash(entry->
domain);
329 list_add_tail_rcu(&entry->
list,
332 INIT_LIST_HEAD(&entry->
list);
339 netlbl_domhsh_audit_add(entry, iter4, NULL,
340 ret_val, audit_info);
341 #if IS_ENABLED(CONFIG_IPV6)
342 netlbl_af6list_foreach_rcu(iter6,
344 netlbl_domhsh_audit_add(entry, NULL, iter6,
345 ret_val, audit_info);
348 netlbl_domhsh_audit_add(entry, NULL, NULL,
349 ret_val, audit_info);
368 #if IS_ENABLED(CONFIG_IPV6)
369 netlbl_af6list_foreach_rcu(iter6,
371 if (netlbl_af6list_search_exact(&iter6->
addr,
384 netlbl_domhsh_audit_add(entry_old, iter4, NULL,
385 ret_val, audit_info);
389 #if IS_ENABLED(CONFIG_IPV6)
390 netlbl_af6list_foreach_safe(iter6, tmp6,
392 netlbl_af6list_remove_entry(iter6);
394 ret_val = netlbl_af6list_add(iter6, old_list6);
395 netlbl_domhsh_audit_add(entry_old, NULL, iter6,
396 ret_val, audit_info);
405 spin_unlock(&netlbl_domhsh_lock);
448 spin_lock(&netlbl_domhsh_lock);
452 list_del_rcu(&entry->
list);
457 spin_unlock(&netlbl_domhsh_lock);
460 if (audit_buf != NULL) {
462 " nlbl_domain=%s res=%u",
464 ret_val == 0 ? 1 : 0);
472 switch (entry->
type) {
513 #if IS_ENABLED(CONFIG_IPV6)
521 entry_map = netlbl_domhsh_search(domain);
523 entry_map = netlbl_domhsh_search_def(domain);
525 goto remove_af4_failure;
527 spin_lock(&netlbl_domhsh_lock);
530 spin_unlock(&netlbl_domhsh_lock);
532 if (entry_addr == NULL)
533 goto remove_af4_failure;
535 goto remove_af4_single_addr;
536 #if IS_ENABLED(CONFIG_IPV6)
538 goto remove_af4_single_addr;
543 remove_af4_single_addr:
577 entry = netlbl_domhsh_search(domain);
579 entry = netlbl_domhsh_search_def(domain);
613 return netlbl_domhsh_search_def(domain);
633 dom_iter = netlbl_domhsh_search_def(domain);
634 if (dom_iter == NULL)
641 if (addr_iter == NULL)
647 #if IS_ENABLED(CONFIG_IPV6)
665 dom_iter = netlbl_domhsh_search_def(domain);
666 if (dom_iter == NULL)
671 addr_iter = netlbl_af6list_search(addr,
673 if (addr_iter == NULL)
707 for (iter_bkt = *skip_bkt;
709 iter_bkt++, chain_cnt = 0) {
711 list_for_each_entry_rcu(iter_entry, iter_list,
list)
712 if (iter_entry->
valid) {
713 if (chain_cnt++ < *skip_chain)
715 ret_val =
callback(iter_entry, cb_arg);
725 *skip_bkt = iter_bkt;
726 *skip_chain = chain_cnt;