summaryrefslogtreecommitdiffstats
path: root/net/netlabel/netlabel_domainhash.c
diff options
context:
space:
mode:
authorHuw Davies <huw@codeweavers.com>2016-06-27 21:02:49 +0200
committerPaul Moore <paul@paul-moore.com>2016-06-27 21:02:49 +0200
commitdc7de73f19962e824243985c046d6a2782d282fc (patch)
treef5db1d7ca4f909a43aea496e406e8cc49775ca1e /net/netlabel/netlabel_domainhash.c
parentnetlabel: Add support for enumerating the CALIPSO DOI list. (diff)
downloadlinux-dc7de73f19962e824243985c046d6a2782d282fc.tar.xz
linux-dc7de73f19962e824243985c046d6a2782d282fc.zip
netlabel: Add support for creating a CALIPSO protocol domain mapping.
This extends the NLBL_MGMT_C_ADD and NLBL_MGMT_C_ADDDEF commands to accept CALIPSO protocol DOIs. Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'net/netlabel/netlabel_domainhash.c')
-rw-r--r--net/netlabel/netlabel_domainhash.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index 3b3b304ccd8b..f1dee0d5e5e2 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -37,10 +37,12 @@
#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"
@@ -223,6 +225,7 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
{
struct audit_buffer *audit_buf;
struct cipso_v4_doi *cipsov4 = NULL;
+ struct calipso_doi *calipso = NULL;
u32 type;
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
@@ -241,12 +244,14 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
struct netlbl_domaddr6_map *map6;
map6 = netlbl_domhsh_addr6_entry(addr6);
type = map6->def.type;
+ calipso = map6->def.calipso;
netlbl_af6list_audit_addr(audit_buf, 0, NULL,
&addr6->addr, &addr6->mask);
#endif /* IPv6 */
} else {
type = entry->def.type;
cipsov4 = entry->def.cipso;
+ calipso = entry->def.calipso;
}
switch (type) {
case NETLBL_NLTYPE_UNLABELED:
@@ -258,6 +263,12 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
" nlbl_protocol=cipsov4 cipso_doi=%u",
cipsov4->doi);
break;
+ case NETLBL_NLTYPE_CALIPSO:
+ BUG_ON(calipso == NULL);
+ audit_log_format(audit_buf,
+ " nlbl_protocol=calipso calipso_doi=%u",
+ calipso->doi);
+ break;
}
audit_log_format(audit_buf, " res=%u", result == 0 ? 1 : 0);
audit_log_end(audit_buf);
@@ -291,7 +302,8 @@ static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
switch (entry->def.type) {
case NETLBL_NLTYPE_UNLABELED:
- if (entry->def.cipso != NULL || entry->def.addrsel != NULL)
+ if (entry->def.cipso != NULL || entry->def.calipso != NULL ||
+ entry->def.addrsel != NULL)
return -EINVAL;
break;
case NETLBL_NLTYPE_CIPSOV4:
@@ -299,6 +311,11 @@ static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
entry->def.cipso == NULL)
return -EINVAL;
break;
+ case NETLBL_NLTYPE_CALIPSO:
+ if (entry->family != AF_INET6 ||
+ entry->def.calipso == NULL)
+ return -EINVAL;
+ break;
case NETLBL_NLTYPE_ADDRSELECT:
netlbl_af4list_foreach(iter4, &entry->def.addrsel->list4) {
map4 = netlbl_domhsh_addr4_entry(iter4);
@@ -320,6 +337,12 @@ static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
map6 = netlbl_domhsh_addr6_entry(iter6);
switch (map6->def.type) {
case NETLBL_NLTYPE_UNLABELED:
+ if (map6->def.calipso != NULL)
+ return -EINVAL;
+ break;
+ case NETLBL_NLTYPE_CALIPSO:
+ if (map6->def.calipso == NULL)
+ return -EINVAL;
break;
default:
return -EINVAL;
@@ -599,6 +622,10 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
if (ret_val == 0) {
struct netlbl_af4list *iter4;
struct netlbl_domaddr4_map *map4;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct netlbl_af6list *iter6;
+ struct netlbl_domaddr6_map *map6;
+#endif /* IPv6 */
switch (entry->def.type) {
case NETLBL_NLTYPE_ADDRSELECT:
@@ -607,12 +634,22 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
map4 = netlbl_domhsh_addr4_entry(iter4);
cipso_v4_doi_putdef(map4->def.cipso);
}
- /* no need to check the IPv6 list since we currently
- * support only unlabeled protocols for IPv6 */
+#if IS_ENABLED(CONFIG_IPV6)
+ netlbl_af6list_foreach_rcu(iter6,
+ &entry->def.addrsel->list6) {
+ map6 = netlbl_domhsh_addr6_entry(iter6);
+ calipso_doi_putdef(map6->def.calipso);
+ }
+#endif /* IPv6 */
break;
case NETLBL_NLTYPE_CIPSOV4:
cipso_v4_doi_putdef(entry->def.cipso);
break;
+#if IS_ENABLED(CONFIG_IPV6)
+ case NETLBL_NLTYPE_CALIPSO:
+ calipso_doi_putdef(entry->def.calipso);
+ break;
+#endif /* IPv6 */
}
call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
}