Skip to content

Commit dc7de73

Browse files
hdmdaviespcmoore
authored andcommitted
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>
1 parent e1ce69d commit dc7de73

File tree

4 files changed

+89
-5
lines changed

4 files changed

+89
-5
lines changed

net/netlabel/netlabel_domainhash.c

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@
3737
#include <linux/slab.h>
3838
#include <net/netlabel.h>
3939
#include <net/cipso_ipv4.h>
40+
#include <net/calipso.h>
4041
#include <asm/bug.h>
4142

4243
#include "netlabel_mgmt.h"
4344
#include "netlabel_addrlist.h"
45+
#include "netlabel_calipso.h"
4446
#include "netlabel_domainhash.h"
4547
#include "netlabel_user.h"
4648

@@ -223,6 +225,7 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
223225
{
224226
struct audit_buffer *audit_buf;
225227
struct cipso_v4_doi *cipsov4 = NULL;
228+
struct calipso_doi *calipso = NULL;
226229
u32 type;
227230

228231
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,
241244
struct netlbl_domaddr6_map *map6;
242245
map6 = netlbl_domhsh_addr6_entry(addr6);
243246
type = map6->def.type;
247+
calipso = map6->def.calipso;
244248
netlbl_af6list_audit_addr(audit_buf, 0, NULL,
245249
&addr6->addr, &addr6->mask);
246250
#endif /* IPv6 */
247251
} else {
248252
type = entry->def.type;
249253
cipsov4 = entry->def.cipso;
254+
calipso = entry->def.calipso;
250255
}
251256
switch (type) {
252257
case NETLBL_NLTYPE_UNLABELED:
@@ -258,6 +263,12 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
258263
" nlbl_protocol=cipsov4 cipso_doi=%u",
259264
cipsov4->doi);
260265
break;
266+
case NETLBL_NLTYPE_CALIPSO:
267+
BUG_ON(calipso == NULL);
268+
audit_log_format(audit_buf,
269+
" nlbl_protocol=calipso calipso_doi=%u",
270+
calipso->doi);
271+
break;
261272
}
262273
audit_log_format(audit_buf, " res=%u", result == 0 ? 1 : 0);
263274
audit_log_end(audit_buf);
@@ -291,14 +302,20 @@ static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
291302

292303
switch (entry->def.type) {
293304
case NETLBL_NLTYPE_UNLABELED:
294-
if (entry->def.cipso != NULL || entry->def.addrsel != NULL)
305+
if (entry->def.cipso != NULL || entry->def.calipso != NULL ||
306+
entry->def.addrsel != NULL)
295307
return -EINVAL;
296308
break;
297309
case NETLBL_NLTYPE_CIPSOV4:
298310
if (entry->family != AF_INET ||
299311
entry->def.cipso == NULL)
300312
return -EINVAL;
301313
break;
314+
case NETLBL_NLTYPE_CALIPSO:
315+
if (entry->family != AF_INET6 ||
316+
entry->def.calipso == NULL)
317+
return -EINVAL;
318+
break;
302319
case NETLBL_NLTYPE_ADDRSELECT:
303320
netlbl_af4list_foreach(iter4, &entry->def.addrsel->list4) {
304321
map4 = netlbl_domhsh_addr4_entry(iter4);
@@ -320,6 +337,12 @@ static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
320337
map6 = netlbl_domhsh_addr6_entry(iter6);
321338
switch (map6->def.type) {
322339
case NETLBL_NLTYPE_UNLABELED:
340+
if (map6->def.calipso != NULL)
341+
return -EINVAL;
342+
break;
343+
case NETLBL_NLTYPE_CALIPSO:
344+
if (map6->def.calipso == NULL)
345+
return -EINVAL;
323346
break;
324347
default:
325348
return -EINVAL;
@@ -599,6 +622,10 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
599622
if (ret_val == 0) {
600623
struct netlbl_af4list *iter4;
601624
struct netlbl_domaddr4_map *map4;
625+
#if IS_ENABLED(CONFIG_IPV6)
626+
struct netlbl_af6list *iter6;
627+
struct netlbl_domaddr6_map *map6;
628+
#endif /* IPv6 */
602629

603630
switch (entry->def.type) {
604631
case NETLBL_NLTYPE_ADDRSELECT:
@@ -607,12 +634,22 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
607634
map4 = netlbl_domhsh_addr4_entry(iter4);
608635
cipso_v4_doi_putdef(map4->def.cipso);
609636
}
610-
/* no need to check the IPv6 list since we currently
611-
* support only unlabeled protocols for IPv6 */
637+
#if IS_ENABLED(CONFIG_IPV6)
638+
netlbl_af6list_foreach_rcu(iter6,
639+
&entry->def.addrsel->list6) {
640+
map6 = netlbl_domhsh_addr6_entry(iter6);
641+
calipso_doi_putdef(map6->def.calipso);
642+
}
643+
#endif /* IPv6 */
612644
break;
613645
case NETLBL_NLTYPE_CIPSOV4:
614646
cipso_v4_doi_putdef(entry->def.cipso);
615647
break;
648+
#if IS_ENABLED(CONFIG_IPV6)
649+
case NETLBL_NLTYPE_CALIPSO:
650+
calipso_doi_putdef(entry->def.calipso);
651+
break;
652+
#endif /* IPv6 */
616653
}
617654
call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
618655
}

net/netlabel/netlabel_domainhash.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct netlbl_dommap_def {
5151
union {
5252
struct netlbl_domaddr_map *addrsel;
5353
struct cipso_v4_doi *cipso;
54+
struct calipso_doi *calipso;
5455
};
5556
};
5657
#define netlbl_domhsh_addr4_entry(iter) \

net/netlabel/netlabel_mgmt.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@
4141
#include <net/ipv6.h>
4242
#include <net/netlabel.h>
4343
#include <net/cipso_ipv4.h>
44+
#include <net/calipso.h>
4445
#include <linux/atomic.h>
4546

47+
#include "netlabel_calipso.h"
4648
#include "netlabel_domainhash.h"
4749
#include "netlabel_user.h"
4850
#include "netlabel_mgmt.h"
@@ -73,6 +75,7 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
7375
[NLBL_MGMT_A_VERSION] = { .type = NLA_U32 },
7476
[NLBL_MGMT_A_CV4DOI] = { .type = NLA_U32 },
7577
[NLBL_MGMT_A_FAMILY] = { .type = NLA_U16 },
78+
[NLBL_MGMT_A_CLPDOI] = { .type = NLA_U32 },
7679
};
7780

7881
/*
@@ -96,6 +99,9 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
9699
int ret_val = -EINVAL;
97100
struct netlbl_domaddr_map *addrmap = NULL;
98101
struct cipso_v4_doi *cipsov4 = NULL;
102+
#if IS_ENABLED(CONFIG_IPV6)
103+
struct calipso_doi *calipso = NULL;
104+
#endif
99105
u32 tmp_val;
100106
struct netlbl_dom_map *entry = kzalloc(sizeof(*entry), GFP_KERNEL);
101107

@@ -137,6 +143,19 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
137143
entry->family = AF_INET;
138144
entry->def.cipso = cipsov4;
139145
break;
146+
#if IS_ENABLED(CONFIG_IPV6)
147+
case NETLBL_NLTYPE_CALIPSO:
148+
if (!info->attrs[NLBL_MGMT_A_CLPDOI])
149+
goto add_free_domain;
150+
151+
tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CLPDOI]);
152+
calipso = calipso_doi_getdef(tmp_val);
153+
if (calipso == NULL)
154+
goto add_free_domain;
155+
entry->family = AF_INET6;
156+
entry->def.calipso = calipso;
157+
break;
158+
#endif /* IPv6 */
140159
default:
141160
goto add_free_domain;
142161
}
@@ -232,6 +251,8 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
232251
map->list.mask = *mask;
233252
map->list.valid = 1;
234253
map->def.type = entry->def.type;
254+
if (calipso)
255+
map->def.calipso = calipso;
235256

236257
ret_val = netlbl_af6list_add(&map->list, &addrmap->list6);
237258
if (ret_val != 0) {
@@ -255,6 +276,9 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
255276
kfree(addrmap);
256277
add_doi_put_def:
257278
cipso_v4_doi_putdef(cipsov4);
279+
#if IS_ENABLED(CONFIG_IPV6)
280+
calipso_doi_putdef(calipso);
281+
#endif
258282
add_free_domain:
259283
kfree(entry->domain);
260284
add_free_entry:
@@ -357,22 +381,41 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb,
357381
if (ret_val != 0)
358382
return ret_val;
359383

384+
switch (map6->def.type) {
385+
case NETLBL_NLTYPE_CALIPSO:
386+
ret_val = nla_put_u32(skb, NLBL_MGMT_A_CLPDOI,
387+
map6->def.calipso->doi);
388+
if (ret_val != 0)
389+
return ret_val;
390+
break;
391+
}
392+
360393
nla_nest_end(skb, nla_b);
361394
}
362395
#endif /* IPv6 */
363396

364397
nla_nest_end(skb, nla_a);
365398
break;
366399
case NETLBL_NLTYPE_UNLABELED:
367-
ret_val = nla_put_u32(skb,NLBL_MGMT_A_PROTOCOL,entry->def.type);
400+
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
401+
entry->def.type);
368402
break;
369403
case NETLBL_NLTYPE_CIPSOV4:
370-
ret_val = nla_put_u32(skb,NLBL_MGMT_A_PROTOCOL,entry->def.type);
404+
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
405+
entry->def.type);
371406
if (ret_val != 0)
372407
return ret_val;
373408
ret_val = nla_put_u32(skb, NLBL_MGMT_A_CV4DOI,
374409
entry->def.cipso->doi);
375410
break;
411+
case NETLBL_NLTYPE_CALIPSO:
412+
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
413+
entry->def.type);
414+
if (ret_val != 0)
415+
return ret_val;
416+
ret_val = nla_put_u32(skb, NLBL_MGMT_A_CLPDOI,
417+
entry->def.calipso->doi);
418+
break;
376419
}
377420

378421
return ret_val;

net/netlabel/netlabel_mgmt.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ enum {
223223
NLBL_MGMT_A_FAMILY,
224224
/* (NLA_U16)
225225
* The address family */
226+
NLBL_MGMT_A_CLPDOI,
227+
/* (NLA_U32)
228+
* the CALIPSO DOI value */
226229
__NLBL_MGMT_A_MAX,
227230
};
228231
#define NLBL_MGMT_A_MAX (__NLBL_MGMT_A_MAX - 1)

0 commit comments

Comments
 (0)