31 #include <linux/types.h>
32 #include <linux/socket.h>
33 #include <linux/string.h>
35 #include <linux/audit.h>
36 #include <linux/slab.h>
63 static struct genl_family netlbl_cipsov4_gnl_family = {
112 netlbl_cipsov4_genl_policy) != 0)
119 doi_def->
tags[iter++] = nla_get_u8(nla);
142 static int netlbl_cipsov4_add_std(
struct genl_info *info,
159 netlbl_cipsov4_genl_policy) != 0)
168 goto add_std_failure;
172 ret_val = netlbl_cipsov4_add_common(info, doi_def);
174 goto add_std_failure;
181 if (nla_validate_nested(nla_a,
183 netlbl_cipsov4_genl_policy) != 0)
184 goto add_std_failure;
188 if (nla_get_u32(nla_b) >
190 goto add_std_failure;
191 if (nla_get_u32(nla_b) >=
192 doi_def->
map.
std->lvl.local_size)
193 doi_def->
map.
std->lvl.local_size =
194 nla_get_u32(nla_b) + 1;
197 if (nla_get_u32(nla_b) >
199 goto add_std_failure;
200 if (nla_get_u32(nla_b) >=
201 doi_def->
map.
std->lvl.cipso_size)
202 doi_def->
map.
std->lvl.cipso_size =
203 nla_get_u32(nla_b) + 1;
207 doi_def->
map.
std->lvl.local = kcalloc(doi_def->
map.
std->lvl.local_size,
212 goto add_std_failure;
214 doi_def->
map.
std->lvl.cipso = kcalloc(doi_def->
map.
std->lvl.cipso_size,
219 goto add_std_failure;
221 for (iter = 0; iter < doi_def->
map.
std->lvl.local_size; iter++)
223 for (iter = 0; iter < doi_def->
map.
std->lvl.cipso_size; iter++)
228 if (
nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) {
232 lvl_loc = nla_find_nested(nla_a,
234 lvl_rem = nla_find_nested(nla_a,
236 if (lvl_loc ==
NULL || lvl_rem ==
NULL)
237 goto add_std_failure;
238 doi_def->
map.
std->lvl.local[nla_get_u32(lvl_loc)] =
239 nla_get_u32(lvl_rem);
240 doi_def->
map.
std->lvl.cipso[nla_get_u32(lvl_rem)] =
241 nla_get_u32(lvl_loc);
247 netlbl_cipsov4_genl_policy) != 0)
248 goto add_std_failure;
254 if (nla_validate_nested(nla_a,
256 netlbl_cipsov4_genl_policy) != 0)
257 goto add_std_failure;
261 if (nla_get_u32(nla_b) >
263 goto add_std_failure;
264 if (nla_get_u32(nla_b) >=
265 doi_def->
map.
std->cat.local_size)
266 doi_def->
map.
std->cat.local_size =
267 nla_get_u32(nla_b) + 1;
270 if (nla_get_u32(nla_b) >
272 goto add_std_failure;
273 if (nla_get_u32(nla_b) >=
274 doi_def->
map.
std->cat.cipso_size)
275 doi_def->
map.
std->cat.cipso_size =
276 nla_get_u32(nla_b) + 1;
280 doi_def->
map.
std->cat.local = kcalloc(
281 doi_def->
map.
std->cat.local_size,
286 goto add_std_failure;
288 doi_def->
map.
std->cat.cipso = kcalloc(
289 doi_def->
map.
std->cat.cipso_size,
294 goto add_std_failure;
296 for (iter = 0; iter < doi_def->
map.
std->cat.local_size; iter++)
298 for (iter = 0; iter < doi_def->
map.
std->cat.cipso_size; iter++)
303 if (
nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) {
307 cat_loc = nla_find_nested(nla_a,
309 cat_rem = nla_find_nested(nla_a,
311 if (cat_loc ==
NULL || cat_rem ==
NULL)
312 goto add_std_failure;
313 doi_def->
map.
std->cat.local[
314 nla_get_u32(cat_loc)] =
315 nla_get_u32(cat_rem);
316 doi_def->
map.
std->cat.cipso[
317 nla_get_u32(cat_rem)] =
318 nla_get_u32(cat_loc);
324 goto add_std_failure;
344 static int netlbl_cipsov4_add_pass(
struct genl_info *info,
358 ret_val = netlbl_cipsov4_add_common(info, doi_def);
360 goto add_pass_failure;
364 goto add_pass_failure;
383 static int netlbl_cipsov4_add_local(
struct genl_info *info,
397 ret_val = netlbl_cipsov4_add_common(info, doi_def);
399 goto add_local_failure;
403 goto add_local_failure;
431 netlbl_netlink_auditinfo(skb, &audit_info);
434 ret_val = netlbl_cipsov4_add_std(info, &audit_info);
437 ret_val = netlbl_cipsov4_add_pass(info, &audit_info);
440 ret_val = netlbl_cipsov4_add_local(info, &audit_info);
485 if (ans_skb ==
NULL) {
489 data = genlmsg_put_reply(ans_skb, info, &netlbl_cipsov4_gnl_family,
500 if (doi_def ==
NULL) {
502 goto list_failure_lock;
507 goto list_failure_lock;
512 goto list_failure_lock;
518 ret_val = nla_put_u8(ans_skb,
520 doi_def->
tags[iter]);
522 goto list_failure_lock;
524 nla_nest_end(ans_skb, nla_a);
526 switch (doi_def->
type) {
531 goto list_failure_lock;
534 iter < doi_def->
map.
std->lvl.local_size;
536 if (doi_def->
map.
std->lvl.local[iter] ==
540 nla_b = nla_nest_start(ans_skb, NLBL_CIPSOV4_A_MLSLVL);
545 ret_val = nla_put_u32(ans_skb,
550 ret_val = nla_put_u32(ans_skb,
552 doi_def->
map.
std->lvl.local[iter]);
555 nla_nest_end(ans_skb, nla_b);
557 nla_nest_end(ans_skb, nla_a);
565 iter < doi_def->
map.
std->cat.local_size;
567 if (doi_def->
map.
std->cat.local[iter] ==
571 nla_b = nla_nest_start(ans_skb, NLBL_CIPSOV4_A_MLSCAT);
576 ret_val = nla_put_u32(ans_skb,
581 ret_val = nla_put_u32(ans_skb,
583 doi_def->
map.
std->cat.local[iter]);
586 nla_nest_end(ans_skb, nla_b);
588 nla_nest_end(ans_skb, nla_a);
594 genlmsg_end(ans_skb, data);
595 return genlmsg_reply(ans_skb, info);
599 if (nlsze_mult < 4) {
624 static int netlbl_cipsov4_listall_cb(
struct cipso_v4_doi *doi_def,
void *
arg)
631 cb_arg->
seq, &netlbl_cipsov4_gnl_family,
634 goto listall_cb_failure;
638 goto listall_cb_failure;
639 ret_val = nla_put_u32(cb_arg->
skb,
643 goto listall_cb_failure;
645 return genlmsg_end(cb_arg->
skb, data);
648 genlmsg_cancel(cb_arg->
skb, data);
662 static int netlbl_cipsov4_listall(
struct sk_buff *skb,
670 cb_arg.
seq = cb->
nlh->nlmsg_seq;
674 cb->
args[0] = doi_skip;
711 static int netlbl_cipsov4_remove(
struct sk_buff *skb,
struct genl_info *info)
722 netlbl_netlink_auditinfo(skb, &audit_info);
726 netlbl_cipsov4_remove_cb, &cb_arg);
727 if (ret_val == 0 || ret_val == -
ENOENT) {
740 static struct genl_ops netlbl_cipsov4_ops[] = {
744 .policy = netlbl_cipsov4_genl_policy,
745 .doit = netlbl_cipsov4_add,
751 .policy = netlbl_cipsov4_genl_policy,
752 .doit = netlbl_cipsov4_remove,
758 .policy = netlbl_cipsov4_genl_policy,
759 .doit = netlbl_cipsov4_list,
765 .policy = netlbl_cipsov4_genl_policy,
767 .dumpit = netlbl_cipsov4_listall,
786 netlbl_cipsov4_ops,
ARRAY_SIZE(netlbl_cipsov4_ops));