Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 41753
b: refs/heads/master
c: 91b1ed0
h: refs/heads/master
i:
  41751: 9f0bcbe
v: v3
  • Loading branch information
Paul Moore authored and David S. Miller committed Dec 3, 2006
1 parent 2cec5b8 commit dd1e90e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 61 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6ce61a7c2678800cfe59a5f4a41ce8f785b9d355
refs/heads/master: 91b1ed0afdbffbda88c472ef72af37e19b7876fb
113 changes: 53 additions & 60 deletions trunk/net/ipv4/cipso_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -958,35 +958,28 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
* Protocol Handling Functions
*/

#define CIPSO_V4_OPT_LEN_MAX 40
#define CIPSO_V4_HDR_LEN 6

/**
* cipso_v4_gentag_hdr - Generate a CIPSO option header
* @doi_def: the DOI definition
* @len: the total tag length in bytes
* @len: the total tag length in bytes, not including this header
* @buf: the CIPSO option buffer
*
* Description:
* Write a CIPSO header into the beginning of @buffer. Return zero on success,
* negative values on failure.
* Write a CIPSO header into the beginning of @buffer.
*
*/
static int cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
u32 len,
unsigned char *buf)
static void cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
unsigned char *buf,
u32 len)
{
if (CIPSO_V4_HDR_LEN + len > 40)
return -ENOSPC;

buf[0] = IPOPT_CIPSO;
buf[1] = CIPSO_V4_HDR_LEN + len;
*(__be32 *)&buf[2] = htonl(doi_def->doi);

return 0;
}

#define CIPSO_V4_TAG1_CAT_LEN 30

/**
* cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1)
* @doi_def: the DOI definition
Expand All @@ -997,71 +990,50 @@ static int cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
* Description:
* Generate a CIPSO option using the restricted bitmap tag, tag type #1. The
* actual buffer length may be larger than the indicated size due to
* translation between host and network category bitmaps. Returns zero on
* success, negative values on failure.
* translation between host and network category bitmaps. Returns the size of
* the tag on success, negative values on failure.
*
*/
static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr,
unsigned char **buffer,
u32 *buffer_len)
unsigned char *buffer,
u32 buffer_len)
{
int ret_val;
unsigned char *buf = NULL;
u32 buf_len;
u32 tag_len;
u32 level;

if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
return -EPERM;

if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN,
GFP_ATOMIC);
if (buf == NULL)
return -ENOMEM;
ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
if (ret_val != 0)
return ret_val;

if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
ret_val = cipso_v4_map_cat_rbm_hton(doi_def,
secattr->mls_cat,
secattr->mls_cat_len,
&buf[CIPSO_V4_HDR_LEN + 4],
CIPSO_V4_TAG1_CAT_LEN);
&buffer[4],
buffer_len - 4);
if (ret_val < 0)
goto gentag_failure;
return ret_val;

/* This will send packets using the "optimized" format when
* possibile as specified in section 3.4.2.6 of the
* CIPSO draft. */
if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10)
buf_len = 14;
tag_len = 14;
else
buf_len = 4 + ret_val;
} else {
buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC);
if (buf == NULL)
return -ENOMEM;
buf_len = 4;
}

ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
if (ret_val != 0)
goto gentag_failure;

ret_val = cipso_v4_gentag_hdr(doi_def, buf_len, buf);
if (ret_val != 0)
goto gentag_failure;

buf[CIPSO_V4_HDR_LEN] = 0x01;
buf[CIPSO_V4_HDR_LEN + 1] = buf_len;
buf[CIPSO_V4_HDR_LEN + 3] = level;
tag_len = 4 + ret_val;
} else
tag_len = 4;

*buffer = buf;
*buffer_len = CIPSO_V4_HDR_LEN + buf_len;
buffer[0] = 0x01;
buffer[1] = tag_len;
buffer[3] = level;

return 0;

gentag_failure:
kfree(buf);
return ret_val;
return tag_len;
}

/**
Expand Down Expand Up @@ -1284,7 +1256,7 @@ int cipso_v4_socket_setattr(const struct socket *sock,
{
int ret_val = -EPERM;
u32 iter;
unsigned char *buf = NULL;
unsigned char *buf;
u32 buf_len = 0;
u32 opt_len;
struct ip_options *opt = NULL;
Expand All @@ -1300,29 +1272,42 @@ int cipso_v4_socket_setattr(const struct socket *sock,
if (sk == NULL)
return 0;

/* We allocate the maximum CIPSO option size here so we are probably
* being a little wasteful, but it makes our life _much_ easier later
* on and after all we are only talking about 40 bytes. */
buf_len = CIPSO_V4_OPT_LEN_MAX;
buf = kmalloc(buf_len, GFP_ATOMIC);
if (buf == NULL) {
ret_val = -ENOMEM;
goto socket_setattr_failure;
}

/* XXX - This code assumes only one tag per CIPSO option which isn't
* really a good assumption to make but since we only support the MAC
* tags right now it is a safe assumption. */
iter = 0;
do {
memset(buf, 0, buf_len);
switch (doi_def->tags[iter]) {
case CIPSO_V4_TAG_RBITMAP:
ret_val = cipso_v4_gentag_rbm(doi_def,
secattr,
&buf,
&buf_len);
secattr,
&buf[CIPSO_V4_HDR_LEN],
buf_len - CIPSO_V4_HDR_LEN);
break;
default:
ret_val = -EPERM;
goto socket_setattr_failure;
}

iter++;
} while (ret_val != 0 &&
} while (ret_val < 0 &&
iter < CIPSO_V4_TAG_MAXCNT &&
doi_def->tags[iter] != CIPSO_V4_TAG_INVALID);
if (ret_val != 0)
if (ret_val < 0)
goto socket_setattr_failure;
cipso_v4_gentag_hdr(doi_def, buf, ret_val);
buf_len = CIPSO_V4_HDR_LEN + ret_val;

/* We can't use ip_options_get() directly because it makes a call to
* ip_options_get_alloc() which allocates memory with GFP_KERNEL and
Expand Down Expand Up @@ -1396,6 +1381,10 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
rcu_read_unlock();
return -ENOMSG;
}

/* XXX - This code assumes only one tag per CIPSO option which isn't
* really a good assumption to make but since we only support the MAC
* tags right now it is a safe assumption. */
switch (cipso_ptr[6]) {
case CIPSO_V4_TAG_RBITMAP:
ret_val = cipso_v4_parsetag_rbm(doi_def,
Expand Down Expand Up @@ -1458,6 +1447,10 @@ int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
doi_def = cipso_v4_doi_getdef(doi);
if (doi_def == NULL)
goto skbuff_getattr_return;

/* XXX - This code assumes only one tag per CIPSO option which isn't
* really a good assumption to make but since we only support the MAC
* tags right now it is a safe assumption. */
switch (cipso_ptr[6]) {
case CIPSO_V4_TAG_RBITMAP:
ret_val = cipso_v4_parsetag_rbm(doi_def,
Expand Down

0 comments on commit dd1e90e

Please sign in to comment.