提交 fd385855 编写于 作者: P Paul Moore 提交者: David S. Miller

[NetLabel]: rework the Netlink attribute handling (part 2)

At the suggestion of Thomas Graf, rewrite NetLabel's use of Netlink attributes
to better follow the common Netlink attribute usage.
Signed-off-by: NPaul Moore <paul.moore@hp.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 fcd48280
此差异已折叠。
......@@ -34,175 +34,71 @@
#include <net/netlabel.h>
/*
* The following NetLabel payloads are supported by the CIPSO subsystem, all
* of which are preceeded by the nlmsghdr struct.
* The following NetLabel payloads are supported by the CIPSO subsystem.
*
* o ACK:
* Sent by the kernel in response to an applications message, applications
* should never send this message.
* o ADD:
* Sent by an application to add a new DOI mapping table.
*
* +----------------------+-----------------------+
* | seq number (32 bits) | return code (32 bits) |
* +----------------------+-----------------------+
* Required attributes:
*
* seq number: the sequence number of the original message, taken from the
* nlmsghdr structure
* return code: return value, based on errno values
* NLBL_CIPSOV4_A_DOI
* NLBL_CIPSOV4_A_MTYPE
* NLBL_CIPSOV4_A_TAGLST
*
* o ADD:
* Sent by an application to add a new DOI mapping table, after completion
* of the task the kernel should ACK this message.
*
* +---------------+--------------------+---------------------+
* | DOI (32 bits) | map type (32 bits) | tag count (32 bits) | ...
* +---------------+--------------------+---------------------+
*
* +-----------------+
* | tag #X (8 bits) | ... repeated
* +-----------------+
*
* +-------------- ---- --- -- -
* | mapping data
* +-------------- ---- --- -- -
*
* DOI: the DOI value
* map type: the mapping table type (defined in the cipso_ipv4.h header
* as CIPSO_V4_MAP_*)
* tag count: the number of tags, must be greater than zero
* tag: the CIPSO tag for the DOI, tags listed first are given
* higher priorirty when sending packets
* mapping data: specific to the map type (see below)
*
* CIPSO_V4_MAP_STD
*
* +------------------+-----------------------+----------------------+
* | levels (32 bits) | max l level (32 bits) | max r level (8 bits) | ...
* +------------------+-----------------------+----------------------+
*
* +----------------------+---------------------+---------------------+
* | categories (32 bits) | max l cat (32 bits) | max r cat (16 bits) | ...
* +----------------------+---------------------+---------------------+
*
* +--------------------------+-------------------------+
* | local level #X (32 bits) | CIPSO level #X (8 bits) | ... repeated
* +--------------------------+-------------------------+
*
* +-----------------------------+-----------------------------+
* | local category #X (32 bits) | CIPSO category #X (16 bits) | ... repeated
* +-----------------------------+-----------------------------+
*
* levels: the number of level mappings
* max l level: the highest local level
* max r level: the highest remote/CIPSO level
* categories: the number of category mappings
* max l cat: the highest local category
* max r cat: the highest remote/CIPSO category
* local level: the local part of a level mapping
* CIPSO level: the remote/CIPSO part of a level mapping
* local category: the local part of a category mapping
* CIPSO category: the remote/CIPSO part of a category mapping
*
* CIPSO_V4_MAP_PASS
*
* No mapping data is needed for this map type.
* If using CIPSO_V4_MAP_STD the following attributes are required:
*
* NLBL_CIPSOV4_A_MLSLVLLST
* NLBL_CIPSOV4_A_MLSCATLST
*
* If using CIPSO_V4_MAP_PASS no additional attributes are required.
*
* o REMOVE:
* Sent by an application to remove a specific DOI mapping table from the
* CIPSO V4 system. The kernel should ACK this message.
* CIPSO V4 system.
*
* +---------------+
* | DOI (32 bits) |
* +---------------+
* Required attributes:
*
* DOI: the DOI value
* NLBL_CIPSOV4_A_DOI
*
* o LIST:
* Sent by an application to list the details of a DOI definition. The
* kernel should send an ACK on error or a response as indicated below. The
* application generated message format is shown below.
* Sent by an application to list the details of a DOI definition. On
* success the kernel should send a response using the following format.
*
* +---------------+
* | DOI (32 bits) |
* +---------------+
* Required attributes:
*
* DOI: the DOI value
* NLBL_CIPSOV4_A_DOI
*
* The valid response message format depends on the type of the DOI mapping,
* the known formats are shown below.
*
* +--------------------+
* | map type (32 bits) | ...
* +--------------------+
*
* map type: the DOI mapping table type (defined in the cipso_ipv4.h
* header as CIPSO_V4_MAP_*)
*
* (map type == CIPSO_V4_MAP_STD)
*
* +----------------+------------------+----------------------+
* | tags (32 bits) | levels (32 bits) | categories (32 bits) | ...
* +----------------+------------------+----------------------+
* the defined formats are shown below.
*
* +-----------------+
* | tag #X (8 bits) | ... repeated
* +-----------------+
* Required attributes:
*
* +--------------------------+-------------------------+
* | local level #X (32 bits) | CIPSO level #X (8 bits) | ... repeated
* +--------------------------+-------------------------+
* NLBL_CIPSOV4_A_MTYPE
* NLBL_CIPSOV4_A_TAGLST
*
* +-----------------------------+-----------------------------+
* | local category #X (32 bits) | CIPSO category #X (16 bits) | ... repeated
* +-----------------------------+-----------------------------+
* If using CIPSO_V4_MAP_STD the following attributes are required:
*
* tags: the number of CIPSO tag types
* levels: the number of level mappings
* categories: the number of category mappings
* tag: the tag number, tags listed first are given higher
* priority when sending packets
* local level: the local part of a level mapping
* CIPSO level: the remote/CIPSO part of a level mapping
* local category: the local part of a category mapping
* CIPSO category: the remote/CIPSO part of a category mapping
* NLBL_CIPSOV4_A_MLSLVLLST
* NLBL_CIPSOV4_A_MLSCATLST
*
* (map type == CIPSO_V4_MAP_PASS)
*
* +----------------+
* | tags (32 bits) | ...
* +----------------+
*
* +-----------------+
* | tag #X (8 bits) | ... repeated
* +-----------------+
*
* tags: the number of CIPSO tag types
* tag: the tag number, tags listed first are given higher
* priority when sending packets
* If using CIPSO_V4_MAP_PASS no additional attributes are required.
*
* o LISTALL:
* This message is sent by an application to list the valid DOIs on the
* system. There is no payload and the kernel should respond with an ACK
* or the following message.
*
* +---------------------+------------------+-----------------------+
* | DOI count (32 bits) | DOI #X (32 bits) | map type #X (32 bits) |
* +---------------------+------------------+-----------------------+
* system. When sent by an application there is no payload and the
* NLM_F_DUMP flag should be set. The kernel should respond with a series of
* the following messages.
*
* +-----------------------+
* | map type #X (32 bits) | ...
* +-----------------------+
* Required attributes:
*
* DOI count: the number of DOIs
* DOI: the DOI value
* map type: the DOI mapping table type (defined in the cipso_ipv4.h
* header as CIPSO_V4_MAP_*)
* NLBL_CIPSOV4_A_DOI
* NLBL_CIPSOV4_A_MTYPE
*
*/
/* NetLabel CIPSOv4 commands */
enum {
NLBL_CIPSOV4_C_UNSPEC,
NLBL_CIPSOV4_C_ACK,
NLBL_CIPSOV4_C_ADD,
NLBL_CIPSOV4_C_REMOVE,
NLBL_CIPSOV4_C_LIST,
......@@ -211,6 +107,59 @@ enum {
};
#define NLBL_CIPSOV4_C_MAX (__NLBL_CIPSOV4_C_MAX - 1)
/* NetLabel CIPSOv4 attributes */
enum {
NLBL_CIPSOV4_A_UNSPEC,
NLBL_CIPSOV4_A_DOI,
/* (NLA_U32)
* the DOI value */
NLBL_CIPSOV4_A_MTYPE,
/* (NLA_U32)
* the mapping table type (defined in the cipso_ipv4.h header as
* CIPSO_V4_MAP_*) */
NLBL_CIPSOV4_A_TAG,
/* (NLA_U8)
* a CIPSO tag type, meant to be used within a NLBL_CIPSOV4_A_TAGLST
* attribute */
NLBL_CIPSOV4_A_TAGLST,
/* (NLA_NESTED)
* the CIPSO tag list for the DOI, there must be at least one
* NLBL_CIPSOV4_A_TAG attribute, tags listed first are given higher
* priorirty when sending packets */
NLBL_CIPSOV4_A_MLSLVLLOC,
/* (NLA_U32)
* the local MLS sensitivity level */
NLBL_CIPSOV4_A_MLSLVLREM,
/* (NLA_U32)
* the remote MLS sensitivity level */
NLBL_CIPSOV4_A_MLSLVL,
/* (NLA_NESTED)
* a MLS sensitivity level mapping, must contain only one attribute of
* each of the following types: NLBL_CIPSOV4_A_MLSLVLLOC and
* NLBL_CIPSOV4_A_MLSLVLREM */
NLBL_CIPSOV4_A_MLSLVLLST,
/* (NLA_NESTED)
* the CIPSO level mappings, there must be at least one
* NLBL_CIPSOV4_A_MLSLVL attribute */
NLBL_CIPSOV4_A_MLSCATLOC,
/* (NLA_U32)
* the local MLS category */
NLBL_CIPSOV4_A_MLSCATREM,
/* (NLA_U32)
* the remote MLS category */
NLBL_CIPSOV4_A_MLSCAT,
/* (NLA_NESTED)
* a MLS category mapping, must contain only one attribute of each of
* the following types: NLBL_CIPSOV4_A_MLSCATLOC and
* NLBL_CIPSOV4_A_MLSCATREM */
NLBL_CIPSOV4_A_MLSCATLST,
/* (NLA_NESTED)
* the CIPSO category mappings, there must be at least one
* NLBL_CIPSOV4_A_MLSCAT attribute */
__NLBL_CIPSOV4_A_MAX,
};
#define NLBL_CIPSOV4_A_MAX (__NLBL_CIPSOV4_A_MAX - 1)
/* NetLabel protocol functions */
int netlbl_cipsov4_genl_init(void);
......
......@@ -42,15 +42,29 @@
#include "netlabel_user.h"
#include "netlabel_mgmt.h"
/* Argument struct for netlbl_domhsh_walk() */
struct netlbl_domhsh_walk_arg {
struct netlink_callback *nl_cb;
struct sk_buff *skb;
u32 seq;
};
/* NetLabel Generic NETLINK CIPSOv4 family */
static struct genl_family netlbl_mgmt_gnl_family = {
.id = GENL_ID_GENERATE,
.hdrsize = 0,
.name = NETLBL_NLTYPE_MGMT_NAME,
.version = NETLBL_PROTO_VERSION,
.maxattr = 0,
.maxattr = NLBL_MGMT_A_MAX,
};
/* NetLabel Netlink attribute policy */
static struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
[NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING },
[NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 },
[NLBL_MGMT_A_VERSION] = { .type = NLA_U32 },
[NLBL_MGMT_A_CV4DOI] = { .type = NLA_U32 },
};
/*
* NetLabel Command Handlers
......@@ -70,97 +84,62 @@ static struct genl_family netlbl_mgmt_gnl_family = {
static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -EINVAL;
struct nlattr *msg_ptr = netlbl_netlink_payload_data(skb);
int msg_len = netlbl_netlink_payload_len(skb);
u32 count;
struct netlbl_dom_map *entry = NULL;
u32 iter;
size_t tmp_size;
u32 tmp_val;
int tmp_size;
ret_val = netlbl_netlink_cap_check(skb, CAP_NET_ADMIN);
if (ret_val != 0)
goto add_failure;
if (msg_len < NETLBL_LEN_U32)
if (!info->attrs[NLBL_MGMT_A_DOMAIN] ||
!info->attrs[NLBL_MGMT_A_PROTOCOL])
goto add_failure;
count = netlbl_getinc_u32(&msg_ptr, &msg_len);
for (iter = 0; iter < count && msg_len > 0; iter++, entry = NULL) {
if (msg_len <= 0) {
ret_val = -EINVAL;
goto add_failure;
}
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (entry == NULL) {
ret_val = -ENOMEM;
goto add_failure;
}
tmp_size = nla_len(msg_ptr);
if (tmp_size <= 0 || tmp_size > msg_len) {
ret_val = -EINVAL;
goto add_failure;
}
tmp_size = nla_len(info->attrs[NLBL_MGMT_A_DOMAIN]);
entry->domain = kmalloc(tmp_size, GFP_KERNEL);
if (entry->domain == NULL) {
ret_val = -ENOMEM;
goto add_failure;
}
nla_strlcpy(entry->domain, msg_ptr, tmp_size);
entry->domain[tmp_size - 1] = '\0';
msg_ptr = nla_next(msg_ptr, &msg_len);
entry->type = nla_get_u32(info->attrs[NLBL_MGMT_A_PROTOCOL]);
nla_strlcpy(entry->domain, info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size);
if (msg_len < NETLBL_LEN_U32) {
ret_val = -EINVAL;
goto add_failure;
}
tmp_val = netlbl_getinc_u32(&msg_ptr, &msg_len);
entry->type = tmp_val;
switch (tmp_val) {
switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
ret_val = netlbl_domhsh_add(entry);
break;
case NETLBL_NLTYPE_CIPSOV4:
if (msg_len < NETLBL_LEN_U32) {
ret_val = -EINVAL;
if (!info->attrs[NLBL_MGMT_A_CV4DOI])
goto add_failure;
}
tmp_val = netlbl_getinc_u32(&msg_ptr, &msg_len);
/* We should be holding a rcu_read_lock() here
* while we hold the result but since the entry
* will always be deleted when the CIPSO DOI
* is deleted we aren't going to keep the lock. */
tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]);
/* We should be holding a rcu_read_lock() here while we hold
* the result but since the entry will always be deleted when
* the CIPSO DOI is deleted we aren't going to keep the
* lock. */
rcu_read_lock();
entry->type_def.cipsov4 = cipso_v4_doi_getdef(tmp_val);
if (entry->type_def.cipsov4 == NULL) {
rcu_read_unlock();
ret_val = -EINVAL;
goto add_failure;
}
ret_val = netlbl_domhsh_add(entry);
rcu_read_unlock();
break;
default:
ret_val = -EINVAL;
goto add_failure;
}
if (ret_val != 0)
goto add_failure;
}
netlbl_netlink_send_ack(info,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_ACK,
NETLBL_E_OK);
return 0;
add_failure:
if (entry)
kfree(entry->domain);
kfree(entry);
netlbl_netlink_send_ack(info,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_ACK,
-ret_val);
return ret_val;
}
......@@ -176,89 +155,100 @@ static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
*/
static int netlbl_mgmt_remove(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -EINVAL;
struct nlattr *msg_ptr = netlbl_netlink_payload_data(skb);
int msg_len = netlbl_netlink_payload_len(skb);
u32 count;
u32 iter;
int tmp_size;
unsigned char *domain;
ret_val = netlbl_netlink_cap_check(skb, CAP_NET_ADMIN);
if (ret_val != 0)
goto remove_return;
if (msg_len < NETLBL_LEN_U32)
goto remove_return;
count = netlbl_getinc_u32(&msg_ptr, &msg_len);
for (iter = 0; iter < count && msg_len > 0; iter++) {
if (msg_len <= 0) {
ret_val = -EINVAL;
goto remove_return;
}
tmp_size = nla_len(msg_ptr);
domain = nla_data(msg_ptr);
if (tmp_size <= 0 || tmp_size > msg_len ||
domain[tmp_size - 1] != '\0') {
ret_val = -EINVAL;
goto remove_return;
}
ret_val = netlbl_domhsh_remove(domain);
if (ret_val != 0)
goto remove_return;
msg_ptr = nla_next(msg_ptr, &msg_len);
}
char *domain;
ret_val = 0;
if (!info->attrs[NLBL_MGMT_A_DOMAIN])
return -EINVAL;
remove_return:
netlbl_netlink_send_ack(info,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_ACK,
-ret_val);
return ret_val;
domain = nla_data(info->attrs[NLBL_MGMT_A_DOMAIN]);
return netlbl_domhsh_remove(domain);
}
/**
* netlbl_mgmt_list - Handle a LIST message
* @skb: the NETLINK buffer
* @info: the Generic NETLINK info block
* netlbl_mgmt_listall_cb - netlbl_domhsh_walk() callback for LISTALL
* @entry: the domain mapping hash table entry
* @arg: the netlbl_domhsh_walk_arg structure
*
* Description:
* Process a user generated LIST message and dumps the domain hash table in a
* form suitable for use in a kernel generated LIST message. Returns zero on
* success, negative values on failure.
* This function is designed to be used as a callback to the
* netlbl_domhsh_walk() function for use in generating a response for a LISTALL
* message. Returns the size of the message on success, negative values on
* failure.
*
*/
static int netlbl_mgmt_list(struct sk_buff *skb, struct genl_info *info)
static int netlbl_mgmt_listall_cb(struct netlbl_dom_map *entry, void *arg)
{
int ret_val = -ENOMEM;
struct sk_buff *ans_skb;
struct netlbl_domhsh_walk_arg *cb_arg = arg;
void *data;
ans_skb = netlbl_domhsh_dump(NLMSG_SPACE(GENL_HDRLEN));
if (ans_skb == NULL)
goto list_failure;
netlbl_netlink_hdr_push(ans_skb,
info->snd_pid,
0,
data = netlbl_netlink_hdr_put(cb_arg->skb,
NETLINK_CB(cb_arg->nl_cb->skb).pid,
cb_arg->seq,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_LIST);
ret_val = netlbl_netlink_snd(ans_skb, info->snd_pid);
NLM_F_MULTI,
NLBL_MGMT_C_LISTALL);
if (data == NULL)
goto listall_cb_failure;
ret_val = nla_put_string(cb_arg->skb,
NLBL_MGMT_A_DOMAIN,
entry->domain);
if (ret_val != 0)
goto listall_cb_failure;
ret_val = nla_put_u32(cb_arg->skb, NLBL_MGMT_A_PROTOCOL, entry->type);
if (ret_val != 0)
goto list_failure;
goto listall_cb_failure;
switch (entry->type) {
case NETLBL_NLTYPE_CIPSOV4:
ret_val = nla_put_u32(cb_arg->skb,
NLBL_MGMT_A_CV4DOI,
entry->type_def.cipsov4->doi);
if (ret_val != 0)
goto listall_cb_failure;
break;
}
return 0;
cb_arg->seq++;
return genlmsg_end(cb_arg->skb, data);
list_failure:
netlbl_netlink_send_ack(info,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_ACK,
-ret_val);
listall_cb_failure:
genlmsg_cancel(cb_arg->skb, data);
return ret_val;
}
/**
* netlbl_mgmt_listall - Handle a LISTALL message
* @skb: the NETLINK buffer
* @cb: the NETLINK callback
*
* Description:
* Process a user generated LISTALL message and dumps the domain hash table in
* a form suitable for use in a kernel generated LISTALL message. Returns zero
* on success, negative values on failure.
*
*/
static int netlbl_mgmt_listall(struct sk_buff *skb,
struct netlink_callback *cb)
{
struct netlbl_domhsh_walk_arg cb_arg;
u32 skip_bkt = cb->args[0];
u32 skip_chain = cb->args[1];
cb_arg.nl_cb = cb;
cb_arg.skb = skb;
cb_arg.seq = cb->nlh->nlmsg_seq;
netlbl_domhsh_walk(&skip_bkt,
&skip_chain,
netlbl_mgmt_listall_cb,
&cb_arg);
cb->args[0] = skip_bkt;
cb->args[1] = skip_chain;
return skb->len;
}
/**
* netlbl_mgmt_adddef - Handle an ADDDEF message
* @skb: the NETLINK buffer
......@@ -272,68 +262,51 @@ static int netlbl_mgmt_list(struct sk_buff *skb, struct genl_info *info)
static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -EINVAL;
struct nlattr *msg_ptr = netlbl_netlink_payload_data(skb);
int msg_len = netlbl_netlink_payload_len(skb);
struct netlbl_dom_map *entry = NULL;
u32 tmp_val;
ret_val = netlbl_netlink_cap_check(skb, CAP_NET_ADMIN);
if (ret_val != 0)
goto adddef_failure;
if (msg_len < NETLBL_LEN_U32)
if (!info->attrs[NLBL_MGMT_A_PROTOCOL])
goto adddef_failure;
tmp_val = netlbl_getinc_u32(&msg_ptr, &msg_len);
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (entry == NULL) {
ret_val = -ENOMEM;
goto adddef_failure;
}
entry->type = nla_get_u32(info->attrs[NLBL_MGMT_A_PROTOCOL]);
entry->type = tmp_val;
switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
ret_val = netlbl_domhsh_add_default(entry);
break;
case NETLBL_NLTYPE_CIPSOV4:
if (msg_len < NETLBL_LEN_U32) {
ret_val = -EINVAL;
if (!info->attrs[NLBL_MGMT_A_CV4DOI])
goto adddef_failure;
}
tmp_val = netlbl_getinc_u32(&msg_ptr, &msg_len);
/* We should be holding a rcu_read_lock here while we
* hold the result but since the entry will always be
* deleted when the CIPSO DOI is deleted we are going
* to skip the lock. */
tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]);
/* We should be holding a rcu_read_lock() here while we hold
* the result but since the entry will always be deleted when
* the CIPSO DOI is deleted we aren't going to keep the
* lock. */
rcu_read_lock();
entry->type_def.cipsov4 = cipso_v4_doi_getdef(tmp_val);
if (entry->type_def.cipsov4 == NULL) {
rcu_read_unlock();
ret_val = -EINVAL;
goto adddef_failure;
}
ret_val = netlbl_domhsh_add_default(entry);
rcu_read_unlock();
break;
default:
ret_val = -EINVAL;
goto adddef_failure;
}
if (ret_val != 0)
goto adddef_failure;
netlbl_netlink_send_ack(info,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_ACK,
NETLBL_E_OK);
return 0;
adddef_failure:
kfree(entry);
netlbl_netlink_send_ack(info,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_ACK,
-ret_val);
return ret_val;
}
......@@ -349,20 +322,7 @@ static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
*/
static int netlbl_mgmt_removedef(struct sk_buff *skb, struct genl_info *info)
{
int ret_val;
ret_val = netlbl_netlink_cap_check(skb, CAP_NET_ADMIN);
if (ret_val != 0)
goto removedef_return;
ret_val = netlbl_domhsh_remove_default();
removedef_return:
netlbl_netlink_send_ack(info,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_ACK,
-ret_val);
return ret_val;
return netlbl_domhsh_remove_default();
}
/**
......@@ -379,87 +339,130 @@ static int netlbl_mgmt_removedef(struct sk_buff *skb, struct genl_info *info)
static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -ENOMEM;
struct sk_buff *ans_skb;
struct sk_buff *ans_skb = NULL;
void *data;
struct netlbl_dom_map *entry;
ans_skb = netlbl_domhsh_dump_default(NLMSG_SPACE(GENL_HDRLEN));
ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (ans_skb == NULL)
goto listdef_failure;
netlbl_netlink_hdr_push(ans_skb,
return -ENOMEM;
data = netlbl_netlink_hdr_put(ans_skb,
info->snd_pid,
0,
info->snd_seq,
netlbl_mgmt_gnl_family.id,
0,
NLBL_MGMT_C_LISTDEF);
if (data == NULL)
goto listdef_failure;
ret_val = netlbl_netlink_snd(ans_skb, info->snd_pid);
rcu_read_lock();
entry = netlbl_domhsh_getentry(NULL);
if (entry == NULL) {
ret_val = -ENOENT;
goto listdef_failure_lock;
}
ret_val = nla_put_u32(ans_skb, NLBL_MGMT_A_PROTOCOL, entry->type);
if (ret_val != 0)
goto listdef_failure;
goto listdef_failure_lock;
switch (entry->type) {
case NETLBL_NLTYPE_CIPSOV4:
ret_val = nla_put_u32(ans_skb,
NLBL_MGMT_A_CV4DOI,
entry->type_def.cipsov4->doi);
if (ret_val != 0)
goto listdef_failure_lock;
break;
}
rcu_read_unlock();
genlmsg_end(ans_skb, data);
ret_val = genlmsg_unicast(ans_skb, info->snd_pid);
if (ret_val != 0)
goto listdef_failure;
return 0;
listdef_failure_lock:
rcu_read_unlock();
listdef_failure:
netlbl_netlink_send_ack(info,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_ACK,
-ret_val);
kfree_skb(ans_skb);
return ret_val;
}
/**
* netlbl_mgmt_modules - Handle a MODULES message
* @skb: the NETLINK buffer
* @info: the Generic NETLINK info block
* netlbl_mgmt_protocols_cb - Write an individual PROTOCOL message response
* @skb: the skb to write to
* @seq: the NETLINK sequence number
* @cb: the NETLINK callback
* @protocol: the NetLabel protocol to use in the message
*
* Description:
* Process a user generated MODULES message and respond accordingly.
* This function is to be used in conjunction with netlbl_mgmt_protocols() to
* answer a application's PROTOCOLS message. Returns the size of the message
* on success, negative values on failure.
*
*/
static int netlbl_mgmt_modules(struct sk_buff *skb, struct genl_info *info)
static int netlbl_mgmt_protocols_cb(struct sk_buff *skb,
struct netlink_callback *cb,
u32 protocol)
{
int ret_val = -ENOMEM;
size_t data_size;
u32 mod_count;
struct sk_buff *ans_skb = NULL;
/* unlabeled + cipsov4 */
mod_count = 2;
void *data;
data_size = GENL_HDRLEN + NETLBL_LEN_U32 + mod_count * NETLBL_LEN_U32;
ans_skb = netlbl_netlink_alloc_skb(0, data_size, GFP_KERNEL);
if (ans_skb == NULL)
goto modules_failure;
if (netlbl_netlink_hdr_put(ans_skb,
info->snd_pid,
0,
data = netlbl_netlink_hdr_put(skb,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_MODULES) == NULL)
goto modules_failure;
NLM_F_MULTI,
NLBL_MGMT_C_PROTOCOLS);
if (data == NULL)
goto protocols_cb_failure;
ret_val = nla_put_u32(ans_skb, NLA_U32, mod_count);
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL, protocol);
if (ret_val != 0)
goto modules_failure;
ret_val = nla_put_u32(ans_skb, NLA_U32, NETLBL_NLTYPE_UNLABELED);
if (ret_val != 0)
goto modules_failure;
ret_val = nla_put_u32(ans_skb, NLA_U32, NETLBL_NLTYPE_CIPSOV4);
if (ret_val != 0)
goto modules_failure;
ret_val = netlbl_netlink_snd(ans_skb, info->snd_pid);
if (ret_val != 0)
goto modules_failure;
goto protocols_cb_failure;
return 0;
return genlmsg_end(skb, data);
modules_failure:
kfree_skb(ans_skb);
netlbl_netlink_send_ack(info,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_ACK,
-ret_val);
protocols_cb_failure:
genlmsg_cancel(skb, data);
return ret_val;
}
/**
* netlbl_mgmt_protocols - Handle a PROTOCOLS message
* @skb: the NETLINK buffer
* @cb: the NETLINK callback
*
* Description:
* Process a user generated PROTOCOLS message and respond accordingly.
*
*/
static int netlbl_mgmt_protocols(struct sk_buff *skb,
struct netlink_callback *cb)
{
u32 protos_sent = cb->args[0];
if (protos_sent == 0) {
if (netlbl_mgmt_protocols_cb(skb,
cb,
NETLBL_NLTYPE_UNLABELED) < 0)
goto protocols_return;
protos_sent++;
}
if (protos_sent == 1) {
if (netlbl_mgmt_protocols_cb(skb,
cb,
NETLBL_NLTYPE_CIPSOV4) < 0)
goto protocols_return;
protos_sent++;
}
protocols_return:
cb->args[0] = protos_sent;
return skb->len;
}
/**
* netlbl_mgmt_version - Handle a VERSION message
* @skb: the NETLINK buffer
......@@ -474,35 +477,35 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -ENOMEM;
struct sk_buff *ans_skb = NULL;
void *data;
ans_skb = netlbl_netlink_alloc_skb(0,
GENL_HDRLEN + NETLBL_LEN_U32,
GFP_KERNEL);
ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (ans_skb == NULL)
goto version_failure;
if (netlbl_netlink_hdr_put(ans_skb,
return -ENOMEM;
data = netlbl_netlink_hdr_put(ans_skb,
info->snd_pid,
0,
info->snd_seq,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_VERSION) == NULL)
0,
NLBL_MGMT_C_VERSION);
if (data == NULL)
goto version_failure;
ret_val = nla_put_u32(ans_skb, NLA_U32, NETLBL_PROTO_VERSION);
ret_val = nla_put_u32(ans_skb,
NLBL_MGMT_A_VERSION,
NETLBL_PROTO_VERSION);
if (ret_val != 0)
goto version_failure;
ret_val = netlbl_netlink_snd(ans_skb, info->snd_pid);
genlmsg_end(ans_skb, data);
ret_val = genlmsg_unicast(ans_skb, info->snd_pid);
if (ret_val != 0)
goto version_failure;
return 0;
version_failure:
kfree_skb(ans_skb);
netlbl_netlink_send_ack(info,
netlbl_mgmt_gnl_family.id,
NLBL_MGMT_C_ACK,
-ret_val);
return ret_val;
}
......@@ -513,35 +516,40 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info)
static struct genl_ops netlbl_mgmt_genl_c_add = {
.cmd = NLBL_MGMT_C_ADD,
.flags = 0,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_add,
.dumpit = NULL,
};
static struct genl_ops netlbl_mgmt_genl_c_remove = {
.cmd = NLBL_MGMT_C_REMOVE,
.flags = 0,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_remove,
.dumpit = NULL,
};
static struct genl_ops netlbl_mgmt_genl_c_list = {
.cmd = NLBL_MGMT_C_LIST,
static struct genl_ops netlbl_mgmt_genl_c_listall = {
.cmd = NLBL_MGMT_C_LISTALL,
.flags = 0,
.doit = netlbl_mgmt_list,
.dumpit = NULL,
.policy = netlbl_mgmt_genl_policy,
.doit = NULL,
.dumpit = netlbl_mgmt_listall,
};
static struct genl_ops netlbl_mgmt_genl_c_adddef = {
.cmd = NLBL_MGMT_C_ADDDEF,
.flags = 0,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_adddef,
.dumpit = NULL,
};
static struct genl_ops netlbl_mgmt_genl_c_removedef = {
.cmd = NLBL_MGMT_C_REMOVEDEF,
.flags = 0,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_removedef,
.dumpit = NULL,
};
......@@ -549,20 +557,23 @@ static struct genl_ops netlbl_mgmt_genl_c_removedef = {
static struct genl_ops netlbl_mgmt_genl_c_listdef = {
.cmd = NLBL_MGMT_C_LISTDEF,
.flags = 0,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_listdef,
.dumpit = NULL,
};
static struct genl_ops netlbl_mgmt_genl_c_modules = {
.cmd = NLBL_MGMT_C_MODULES,
static struct genl_ops netlbl_mgmt_genl_c_protocols = {
.cmd = NLBL_MGMT_C_PROTOCOLS,
.flags = 0,
.doit = netlbl_mgmt_modules,
.dumpit = NULL,
.policy = netlbl_mgmt_genl_policy,
.doit = NULL,
.dumpit = netlbl_mgmt_protocols,
};
static struct genl_ops netlbl_mgmt_genl_c_version = {
.cmd = NLBL_MGMT_C_VERSION,
.flags = 0,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_version,
.dumpit = NULL,
};
......@@ -596,7 +607,7 @@ int netlbl_mgmt_genl_init(void)
if (ret_val != 0)
return ret_val;
ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
&netlbl_mgmt_genl_c_list);
&netlbl_mgmt_genl_c_listall);
if (ret_val != 0)
return ret_val;
ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
......@@ -612,7 +623,7 @@ int netlbl_mgmt_genl_init(void)
if (ret_val != 0)
return ret_val;
ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
&netlbl_mgmt_genl_c_modules);
&netlbl_mgmt_genl_c_protocols);
if (ret_val != 0)
return ret_val;
ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
......
......@@ -34,212 +34,137 @@
#include <net/netlabel.h>
/*
* The following NetLabel payloads are supported by the management interface,
* all of which are preceeded by the nlmsghdr struct.
*
* o ACK:
* Sent by the kernel in response to an applications message, applications
* should never send this message.
*
* +----------------------+-----------------------+
* | seq number (32 bits) | return code (32 bits) |
* +----------------------+-----------------------+
*
* seq number: the sequence number of the original message, taken from the
* nlmsghdr structure
* return code: return value, based on errno values
* The following NetLabel payloads are supported by the management interface.
*
* o ADD:
* Sent by an application to add a domain mapping to the NetLabel system.
* The kernel should respond with an ACK.
*
* +-------------------+
* | domains (32 bits) | ...
* +-------------------+
*
* domains: the number of domains in the message
*
* +--------------------------+-------------------------+
* | domain string (variable) | protocol type (32 bits) | ...
* +--------------------------+-------------------------+
*
* +-------------- ---- --- -- -
* | mapping data ... repeated
* +-------------- ---- --- -- -
* Required attributes:
*
* domain string: the domain string, NULL terminated
* protocol type: the protocol type (defined by NETLBL_NLTYPE_*)
* mapping data: specific to the map type (see below)
* NLBL_MGMT_A_DOMAIN
* NLBL_MGMT_A_PROTOCOL
*
* NETLBL_NLTYPE_UNLABELED
* If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required:
*
* No mapping data for this protocol type.
* NLBL_MGMT_A_CV4DOI
*
* NETLBL_NLTYPE_CIPSOV4
*
* +---------------+
* | doi (32 bits) |
* +---------------+
*
* doi: the CIPSO DOI value
* If using NETLBL_NLTYPE_UNLABELED no other attributes are required.
*
* o REMOVE:
* Sent by an application to remove a domain mapping from the NetLabel
* system. The kernel should ACK this message.
*
* +-------------------+
* | domains (32 bits) | ...
* +-------------------+
* system.
*
* domains: the number of domains in the message
* Required attributes:
*
* +--------------------------+
* | domain string (variable) | ...
* +--------------------------+
* NLBL_MGMT_A_DOMAIN
*
* domain string: the domain string, NULL terminated
*
* o LIST:
* o LISTALL:
* This message can be sent either from an application or by the kernel in
* response to an application generated LIST message. When sent by an
* application there is no payload. The kernel should respond to a LIST
* message either with a LIST message on success or an ACK message on
* failure.
*
* +-------------------+
* | domains (32 bits) | ...
* +-------------------+
*
* domains: the number of domains in the message
* response to an application generated LISTALL message. When sent by an
* application there is no payload and the NLM_F_DUMP flag should be set.
* The kernel should respond with a series of the following messages.
*
* +--------------------------+
* | domain string (variable) | ...
* +--------------------------+
* Required attributes:
*
* +-------------------------+-------------- ---- --- -- -
* | protocol type (32 bits) | mapping data ... repeated
* +-------------------------+-------------- ---- --- -- -
* NLBL_MGMT_A_DOMAIN
* NLBL_MGMT_A_PROTOCOL
*
* domain string: the domain string, NULL terminated
* protocol type: the protocol type (defined by NETLBL_NLTYPE_*)
* mapping data: specific to the map type (see below)
* If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required:
*
* NETLBL_NLTYPE_UNLABELED
* NLBL_MGMT_A_CV4DOI
*
* No mapping data for this protocol type.
*
* NETLBL_NLTYPE_CIPSOV4
*
* +----------------+---------------+
* | type (32 bits) | doi (32 bits) |
* +----------------+---------------+
*
* type: the CIPSO mapping table type (defined in the cipso_ipv4.h header
* as CIPSO_V4_MAP_*)
* doi: the CIPSO DOI value
* If using NETLBL_NLTYPE_UNLABELED no other attributes are required.
*
* o ADDDEF:
* Sent by an application to set the default domain mapping for the NetLabel
* system. The kernel should respond with an ACK.
* system.
*
* +-------------------------+-------------- ---- --- -- -
* | protocol type (32 bits) | mapping data ... repeated
* +-------------------------+-------------- ---- --- -- -
* Required attributes:
*
* protocol type: the protocol type (defined by NETLBL_NLTYPE_*)
* mapping data: specific to the map type (see below)
* NLBL_MGMT_A_PROTOCOL
*
* NETLBL_NLTYPE_UNLABELED
* If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required:
*
* No mapping data for this protocol type.
* NLBL_MGMT_A_CV4DOI
*
* NETLBL_NLTYPE_CIPSOV4
*
* +---------------+
* | doi (32 bits) |
* +---------------+
*
* doi: the CIPSO DOI value
* If using NETLBL_NLTYPE_UNLABELED no other attributes are required.
*
* o REMOVEDEF:
* Sent by an application to remove the default domain mapping from the
* NetLabel system, there is no payload. The kernel should ACK this message.
* NetLabel system, there is no payload.
*
* o LISTDEF:
* This message can be sent either from an application or by the kernel in
* response to an application generated LISTDEF message. When sent by an
* application there is no payload. The kernel should respond to a
* LISTDEF message either with a LISTDEF message on success or an ACK message
* on failure.
*
* +-------------------------+-------------- ---- --- -- -
* | protocol type (32 bits) | mapping data ... repeated
* +-------------------------+-------------- ---- --- -- -
* application there is no payload. On success the kernel should send a
* response using the following format.
*
* protocol type: the protocol type (defined by NETLBL_NLTYPE_*)
* mapping data: specific to the map type (see below)
* Required attributes:
*
* NETLBL_NLTYPE_UNLABELED
* NLBL_MGMT_A_PROTOCOL
*
* No mapping data for this protocol type.
* If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required:
*
* NETLBL_NLTYPE_CIPSOV4
* NLBL_MGMT_A_CV4DOI
*
* +----------------+---------------+
* | type (32 bits) | doi (32 bits) |
* +----------------+---------------+
* If using NETLBL_NLTYPE_UNLABELED no other attributes are required.
*
* type: the CIPSO mapping table type (defined in the cipso_ipv4.h header
* as CIPSO_V4_MAP_*)
* doi: the CIPSO DOI value
* o PROTOCOLS:
* Sent by an application to request a list of configured NetLabel protocols
* in the kernel. When sent by an application there is no payload and the
* NLM_F_DUMP flag should be set. The kernel should respond with a series of
* the following messages.
*
* o MODULES:
* Sent by an application to request a list of configured NetLabel modules
* in the kernel. When sent by an application there is no payload.
* Required attributes:
*
* +-------------------+
* | modules (32 bits) | ...
* +-------------------+
*
* modules: the number of modules in the message, if this is an application
* generated message and the value is zero then return a list of
* the configured modules
*
* +------------------+
* | module (32 bits) | ... repeated
* +------------------+
*
* module: the module number as defined by NETLBL_NLTYPE_*
* NLBL_MGMT_A_PROTOCOL
*
* o VERSION:
* Sent by an application to request the NetLabel version string. When sent
* by an application there is no payload. This message type is also used by
* the kernel to respond to an VERSION request.
* Sent by an application to request the NetLabel version. When sent by an
* application there is no payload. This message type is also used by the
* kernel to respond to an VERSION request.
*
* +-------------------+
* | version (32 bits) |
* +-------------------+
* Required attributes:
*
* version: the protocol version number
* NLBL_MGMT_A_VERSION
*
*/
/* NetLabel Management commands */
enum {
NLBL_MGMT_C_UNSPEC,
NLBL_MGMT_C_ACK,
NLBL_MGMT_C_ADD,
NLBL_MGMT_C_REMOVE,
NLBL_MGMT_C_LIST,
NLBL_MGMT_C_LISTALL,
NLBL_MGMT_C_ADDDEF,
NLBL_MGMT_C_REMOVEDEF,
NLBL_MGMT_C_LISTDEF,
NLBL_MGMT_C_MODULES,
NLBL_MGMT_C_PROTOCOLS,
NLBL_MGMT_C_VERSION,
__NLBL_MGMT_C_MAX,
};
#define NLBL_MGMT_C_MAX (__NLBL_MGMT_C_MAX - 1)
/* NetLabel Management attributes */
enum {
NLBL_MGMT_A_UNSPEC,
NLBL_MGMT_A_DOMAIN,
/* (NLA_NUL_STRING)
* the NULL terminated LSM domain string */
NLBL_MGMT_A_PROTOCOL,
/* (NLA_U32)
* the NetLabel protocol type (defined by NETLBL_NLTYPE_*) */
NLBL_MGMT_A_VERSION,
/* (NLA_U32)
* the NetLabel protocol version number (defined by
* NETLBL_PROTO_VERSION) */
NLBL_MGMT_A_CV4DOI,
/* (NLA_U32)
* the CIPSOv4 DOI value */
__NLBL_MGMT_A_MAX,
};
#define NLBL_MGMT_A_MAX (__NLBL_MGMT_A_MAX - 1)
/* NetLabel protocol functions */
int netlbl_mgmt_genl_init(void);
......
......@@ -55,9 +55,13 @@ static struct genl_family netlbl_unlabel_gnl_family = {
.hdrsize = 0,
.name = NETLBL_NLTYPE_UNLABELED_NAME,
.version = NETLBL_PROTO_VERSION,
.maxattr = 0,
.maxattr = NLBL_UNLABEL_A_MAX,
};
/* NetLabel Netlink attribute policy */
static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
[NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
};
/*
* NetLabel Command Handlers
......@@ -75,31 +79,18 @@ static struct genl_family netlbl_unlabel_gnl_family = {
*/
static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info)
{
int ret_val;
struct nlattr *data = netlbl_netlink_payload_data(skb);
u32 value;
ret_val = netlbl_netlink_cap_check(skb, CAP_NET_ADMIN);
if (ret_val != 0)
return ret_val;
int ret_val = -EINVAL;
u8 value;
if (netlbl_netlink_payload_len(skb) == NETLBL_LEN_U32) {
value = nla_get_u32(data);
if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) {
value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]);
if (value == 1 || value == 0) {
atomic_set(&netlabel_unlabel_accept_flg, value);
netlbl_netlink_send_ack(info,
netlbl_unlabel_gnl_family.id,
NLBL_UNLABEL_C_ACK,
NETLBL_E_OK);
return 0;
ret_val = 0;
}
}
netlbl_netlink_send_ack(info,
netlbl_unlabel_gnl_family.id,
NLBL_UNLABEL_C_ACK,
EINVAL);
return -EINVAL;
return ret_val;
}
/**
......@@ -114,39 +105,39 @@ static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info)
*/
static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -ENOMEM;
int ret_val = -EINVAL;
struct sk_buff *ans_skb;
void *data;
ans_skb = netlbl_netlink_alloc_skb(0,
GENL_HDRLEN + NETLBL_LEN_U32,
GFP_KERNEL);
ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (ans_skb == NULL)
goto list_failure;
if (netlbl_netlink_hdr_put(ans_skb,
data = netlbl_netlink_hdr_put(ans_skb,
info->snd_pid,
0,
info->snd_seq,
netlbl_unlabel_gnl_family.id,
NLBL_UNLABEL_C_LIST) == NULL)
0,
NLBL_UNLABEL_C_LIST);
if (data == NULL) {
ret_val = -ENOMEM;
goto list_failure;
}
ret_val = nla_put_u32(ans_skb,
NLA_U32,
ret_val = nla_put_u8(ans_skb,
NLBL_UNLABEL_A_ACPTFLG,
atomic_read(&netlabel_unlabel_accept_flg));
if (ret_val != 0)
goto list_failure;
ret_val = netlbl_netlink_snd(ans_skb, info->snd_pid);
genlmsg_end(ans_skb, data);
ret_val = genlmsg_unicast(ans_skb, info->snd_pid);
if (ret_val != 0)
goto list_failure;
return 0;
list_failure:
netlbl_netlink_send_ack(info,
netlbl_unlabel_gnl_family.id,
NLBL_UNLABEL_C_ACK,
-ret_val);
kfree(ans_skb);
return ret_val;
}
......@@ -157,7 +148,8 @@ static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info)
static struct genl_ops netlbl_unlabel_genl_c_accept = {
.cmd = NLBL_UNLABEL_C_ACCEPT,
.flags = 0,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_accept,
.dumpit = NULL,
};
......@@ -165,6 +157,7 @@ static struct genl_ops netlbl_unlabel_genl_c_accept = {
static struct genl_ops netlbl_unlabel_genl_c_list = {
.cmd = NLBL_UNLABEL_C_LIST,
.flags = 0,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_list,
.dumpit = NULL,
};
......@@ -218,10 +211,8 @@ int netlbl_unlabel_genl_init(void)
*/
int netlbl_unlabel_getattr(struct netlbl_lsm_secattr *secattr)
{
if (atomic_read(&netlabel_unlabel_accept_flg) == 1) {
memset(secattr, 0, sizeof(*secattr));
return 0;
}
if (atomic_read(&netlabel_unlabel_accept_flg) == 1)
return netlbl_secattr_init(secattr);
return -ENOMSG;
}
......
......@@ -36,56 +36,47 @@
/*
* The following NetLabel payloads are supported by the Unlabeled subsystem.
*
* o ACK:
* Sent by the kernel in response to an applications message, applications
* should never send this message.
*
* +----------------------+-----------------------+
* | seq number (32 bits) | return code (32 bits) |
* +----------------------+-----------------------+
*
* seq number: the sequence number of the original message, taken from the
* nlmsghdr structure
* return code: return value, based on errno values
*
* o ACCEPT
* This message is sent from an application to specify if the kernel should
* allow unlabled packets to pass if they do not match any of the static
* mappings defined in the unlabeled module.
*
* +-----------------+
* | allow (32 bits) |
* +-----------------+
* Required attributes:
*
* allow: if true (1) then allow the packets to pass, if false (0) then
* reject the packets
* NLBL_UNLABEL_A_ACPTFLG
*
* o LIST
* This message can be sent either from an application or by the kernel in
* response to an application generated LIST message. When sent by an
* application there is no payload. The kernel should respond to a LIST
* message either with a LIST message on success or an ACK message on
* failure.
* message with a LIST message on success.
*
* +-----------------------+
* | accept flag (32 bits) |
* +-----------------------+
* Required attributes:
*
* accept flag: if true (1) then unlabeled packets are allowed to pass,
* if false (0) then unlabeled packets are rejected
* NLBL_UNLABEL_A_ACPTFLG
*
*/
/* NetLabel Unlabeled commands */
enum {
NLBL_UNLABEL_C_UNSPEC,
NLBL_UNLABEL_C_ACK,
NLBL_UNLABEL_C_ACCEPT,
NLBL_UNLABEL_C_LIST,
__NLBL_UNLABEL_C_MAX,
};
#define NLBL_UNLABEL_C_MAX (__NLBL_UNLABEL_C_MAX - 1)
/* NetLabel Unlabeled attributes */
enum {
NLBL_UNLABEL_A_UNSPEC,
NLBL_UNLABEL_A_ACPTFLG,
/* (NLA_U8)
* if true then unlabeled packets are allowed to pass, else unlabeled
* packets are rejected */
__NLBL_UNLABEL_A_MAX,
};
#define NLBL_UNLABEL_A_MAX (__NLBL_UNLABEL_A_MAX - 1)
/* NetLabel protocol functions */
int netlbl_unlabel_genl_init(void);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册