From a5e34490c3160e09814403d040765b0ae0003121 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Mon, 27 Jun 2016 15:02:47 -0400 Subject: netlabel: Add support for querying a CALIPSO DOI. Query a specified DOI through the NLBL_CALIPSO_C_LIST command. It requires the attribute: NLBL_CALIPSO_A_DOI. The reply will contain: NLBL_CALIPSO_A_MTYPE Signed-off-by: Huw Davies Signed-off-by: Paul Moore --- net/netlabel/netlabel_calipso.c | 102 ++++++++++++++++++++++++++++++++++++++++ net/netlabel/netlabel_calipso.h | 19 ++++++++ 2 files changed, 121 insertions(+) (limited to 'net/netlabel') diff --git a/net/netlabel/netlabel_calipso.c b/net/netlabel/netlabel_calipso.c index 8a113f91b7a1..6161170dc5f4 100644 --- a/net/netlabel/netlabel_calipso.c +++ b/net/netlabel/netlabel_calipso.c @@ -124,6 +124,65 @@ static int netlbl_calipso_add(struct sk_buff *skb, struct genl_info *info) return ret_val; } +/** + * netlbl_calipso_list - Handle a LIST message + * @skb: the NETLINK buffer + * @info: the Generic NETLINK info block + * + * Description: + * Process a user generated LIST message and respond accordingly. + * Returns zero on success and negative values on error. + * + */ +static int netlbl_calipso_list(struct sk_buff *skb, struct genl_info *info) +{ + int ret_val; + struct sk_buff *ans_skb = NULL; + void *data; + u32 doi; + struct calipso_doi *doi_def; + + if (!info->attrs[NLBL_CALIPSO_A_DOI]) { + ret_val = -EINVAL; + goto list_failure; + } + + doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]); + + doi_def = calipso_doi_getdef(doi); + if (!doi_def) { + ret_val = -EINVAL; + goto list_failure; + } + + ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!ans_skb) { + ret_val = -ENOMEM; + goto list_failure_put; + } + data = genlmsg_put_reply(ans_skb, info, &netlbl_calipso_gnl_family, + 0, NLBL_CALIPSO_C_LIST); + if (!data) { + ret_val = -ENOMEM; + goto list_failure_put; + } + + ret_val = nla_put_u32(ans_skb, NLBL_CALIPSO_A_MTYPE, doi_def->type); + if (ret_val != 0) + goto list_failure_put; + + calipso_doi_putdef(doi_def); + + genlmsg_end(ans_skb, data); + return genlmsg_reply(ans_skb, info); + +list_failure_put: + calipso_doi_putdef(doi_def); +list_failure: + kfree_skb(ans_skb); + return ret_val; +} + /* NetLabel Generic NETLINK Command Definitions */ @@ -135,6 +194,13 @@ static const struct genl_ops netlbl_calipso_ops[] = { .doit = netlbl_calipso_add, .dumpit = NULL, }, + { + .cmd = NLBL_CALIPSO_C_LIST, + .flags = 0, + .policy = calipso_genl_policy, + .doit = netlbl_calipso_list, + .dumpit = NULL, + }, }; /* NetLabel Generic NETLINK Protocol Functions @@ -214,3 +280,39 @@ void calipso_doi_free(struct calipso_doi *doi_def) if (ops) ops->doi_free(doi_def); } + +/** + * calipso_doi_getdef - Returns a reference to a valid DOI definition + * @doi: the DOI value + * + * Description: + * Searches for a valid DOI definition and if one is found it is returned to + * the caller. Otherwise NULL is returned. The caller must ensure that + * calipso_doi_putdef() is called when the caller is done. + * + */ +struct calipso_doi *calipso_doi_getdef(u32 doi) +{ + struct calipso_doi *ret_val = NULL; + const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); + + if (ops) + ret_val = ops->doi_getdef(doi); + return ret_val; +} + +/** + * calipso_doi_putdef - Releases a reference for the given DOI definition + * @doi_def: the DOI definition + * + * Description: + * Releases a DOI definition reference obtained from calipso_doi_getdef(). + * + */ +void calipso_doi_putdef(struct calipso_doi *doi_def) +{ + const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); + + if (ops) + ops->doi_putdef(doi_def); +} diff --git a/net/netlabel/netlabel_calipso.h b/net/netlabel/netlabel_calipso.h index f78790a6ce4f..6da737a9f37a 100644 --- a/net/netlabel/netlabel_calipso.h +++ b/net/netlabel/netlabel_calipso.h @@ -46,6 +46,23 @@ * * If using CALIPSO_MAP_PASS no additional attributes are required. * + * o LIST: + * Sent by an application to list the details of a DOI definition. On + * success the kernel should send a response using the following format. + * + * Required attributes: + * + * NLBL_CALIPSO_A_DOI + * + * The valid response message format depends on the type of the DOI mapping, + * the defined formats are shown below. + * + * Required attributes: + * + * NLBL_CALIPSO_A_MTYPE + * + * If using CALIPSO_MAP_PASS no additional attributes are required. + * */ /* NetLabel CALIPSO commands */ @@ -86,5 +103,7 @@ static inline int netlbl_calipso_genl_init(void) int calipso_doi_add(struct calipso_doi *doi_def, struct netlbl_audit *audit_info); void calipso_doi_free(struct calipso_doi *doi_def); +struct calipso_doi *calipso_doi_getdef(u32 doi); +void calipso_doi_putdef(struct calipso_doi *doi_def); #endif -- cgit v1.2.3