Commit 63e15a36 authored by Jon Grimm's avatar Jon Grimm

[SCTP] sctp_params cleanup (jgrimm)

naming, purge typdef
add macro for walking parameters, stronger validity checks
parent cca1b32f
......@@ -418,6 +418,18 @@ static inline size_t get_user_iov_size(struct iovec *iov, int iovlen)
return retval;
}
/* Walk through a list of TLV parameters. Don't trust the
* individual parameter lengths and instead depend on
* the chunk length to indicate when to stop. Make sure
* there is room for a param header too.
*/
#define sctp_walk_params(pos, chunk, member)\
_sctp_walk_params(((union sctp_params)(pos)), (chunk), member)
#define _sctp_walk_params(pos, chunk, member)\
for (pos.v = (void *)&chunk->member;\
pos.v <= (void *)chunk + ntohs(chunk->chunk_hdr.length) - sizeof(sctp_paramhdr_t);\
pos.v += WORD_ROUND(ntohs(pos.p->length)))
/* Round an int up to the next multiple of 4. */
#define WORD_ROUND(s) (((s)+3)&~3)
......
......@@ -206,9 +206,6 @@ sctp_association_t *sctp_make_temp_asoc(const sctp_endpoint_t *,
sctp_chunk_t *,
const int priority);
__u32 sctp_generate_verification_tag(void);
sctpParam_t sctp_get_my_addrs_raw(const sctp_association_t *,
const int priority, int *addrs_len);
void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag);
/* Prototypes for chunk-building functions. */
......@@ -336,7 +333,7 @@ __u32 sctp_generate_tsn(const sctp_endpoint_t *);
/* 4th level prototypes */
void sctp_param2sockaddr(sockaddr_storage_t *addr, sctp_addr_param_t *,
__u16 port);
int sctp_addr2sockaddr(const sctpParam_t, sockaddr_storage_t *);
int sctp_addr2sockaddr(const union sctp_params, sockaddr_storage_t *);
int sockaddr2sctp_addr(const sockaddr_storage_t *, sctp_addr_param_t *);
/* Extern declarations for major data structures. */
......
......@@ -356,20 +356,6 @@ typedef struct sctp_signed_cookie {
} sctp_signed_cookie_t;
/* This convenience type allows us to avoid casting when walking
* through a parameter list.
*/
typedef union {
__u8 *v;
sctp_paramhdr_t *p;
sctp_cookie_preserve_param_t *bht;
sctp_hostname_param_t *dns;
sctp_cookie_param_t *cookie;
sctp_supported_addrs_param_t *sat;
sctp_ipv4addr_param_t *v4;
sctp_ipv6addr_param_t *v6;
} sctpParam_t;
/* This is another convenience type to allocate memory for address
* params for the maximum size and pass such structures around
......@@ -380,6 +366,21 @@ typedef union {
sctp_ipv6addr_param_t v6;
} sctp_addr_param_t;
/* A convenience type to allow walking through the various
* parameters and avoid casting all over the place.
*/
union sctp_params {
void *v;
sctp_paramhdr_t *p;
sctp_cookie_preserve_param_t *life;
sctp_hostname_param_t *dns;
sctp_cookie_param_t *cookie;
sctp_supported_addrs_param_t *sat;
sctp_ipv4addr_param_t *v4;
sctp_ipv6addr_param_t *v6;
sctp_addr_param_t *addr;
};
/* RFC 2960. Section 3.3.5 Heartbeat.
* Heartbeat Information: variable length
* The Sender-specific Heartbeat Info field should normally include
......@@ -430,7 +431,7 @@ struct SCTP_chunk {
*/
/* We point this at the FIRST TLV parameter to chunk_hdr. */
sctpParam_t param_hdr;
union sctp_params param_hdr;
union {
__u8 *v;
sctp_datahdr_t *data_hdr;
......@@ -885,9 +886,9 @@ int sctp_add_bind_addr(sctp_bind_addr_t *, sockaddr_storage_t *,
int priority);
int sctp_del_bind_addr(sctp_bind_addr_t *, sockaddr_storage_t *);
int sctp_bind_addr_has_addr(sctp_bind_addr_t *, const sockaddr_storage_t *);
sctpParam_t sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp,
int *addrs_len,
int priority);
union sctp_params sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp,
int *addrs_len,
int priority);
int sctp_raw_to_bind_addrs(sctp_bind_addr_t *bp,
__u8 *raw_addr_list,
int addrs_len,
......@@ -1053,19 +1054,19 @@ int sctp_verify_init(const sctp_association_t *asoc,
sctp_chunk_t *chunk,
sctp_chunk_t **err_chunk);
int sctp_verify_param(const sctp_association_t *asoc,
sctpParam_t param,
union sctp_params param,
sctp_cid_t cid,
sctp_chunk_t *chunk,
sctp_chunk_t **err_chunk);
int sctp_process_unk_param(const sctp_association_t *asoc,
sctpParam_t param,
union sctp_params param,
sctp_chunk_t *chunk,
sctp_chunk_t **err_chunk);
void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
const sockaddr_storage_t *peer_addr,
sctp_init_chunk_t *peer_init, int priority);
int sctp_process_param(sctp_association_t *asoc,
sctpParam_t param,
union sctp_params param,
const sockaddr_storage_t *peer_addr,
sctp_cid_t cid, int priority);
__u32 sctp_generate_tag(const sctp_endpoint_t *ep);
......
......@@ -196,18 +196,16 @@ int sctp_del_bind_addr(sctp_bind_addr_t *bp, sockaddr_storage_t *del_addr)
*
* The second argument is the return value for the length.
*/
sctpParam_t sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp, int *addrs_len,
int priority)
union sctp_params sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp,
int *addrs_len, int priority)
{
sctpParam_t addrparms;
sctpParam_t retval;
union sctp_params addrparms;
union sctp_params retval;
int addrparms_len;
sctp_addr_param_t rawaddr;
int len;
struct sockaddr_storage_list *addr;
struct list_head *pos;
retval.v = NULL;
addrparms_len = 0;
len = 0;
......@@ -216,11 +214,11 @@ sctpParam_t sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp, int *addrs_len,
len += sizeof(sctp_addr_param_t);
}
addrparms.v = kmalloc(len, priority);
if (!addrparms.v)
retval.v = kmalloc(len, priority);
if (!retval.v)
goto end_raw;
retval = addrparms;
addrparms = retval;
list_for_each(pos, &bp->address_list) {
addr = list_entry(pos, struct sockaddr_storage_list, list);
......
/* SCTP kernel reference Implementation
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 International Business Machines Corp.
* Copyright (c) 2001-2002 Intel Corp.
* Copyright (c) 2001-2002 International Business Machines Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
......@@ -166,7 +166,7 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc,
int priority)
{
sctp_inithdr_t init;
sctpParam_t addrs;
union sctp_params addrs;
size_t chunksize;
sctp_chunk_t *retval = NULL;
int addrs_len = 0;
......@@ -228,7 +228,7 @@ sctp_chunk_t *sctp_make_init_ack(const sctp_association_t *asoc,
{
sctp_inithdr_t initack;
sctp_chunk_t *retval;
sctpParam_t addrs;
union sctp_params addrs;
int addrs_len;
sctp_cookie_param_t *cookie;
int cookie_len;
......@@ -1482,21 +1482,17 @@ int sctp_verify_init(const sctp_association_t *asoc,
sctp_chunk_t *chunk,
sctp_chunk_t **err_chk_p)
{
sctpParam_t param;
uint8_t *end;
union sctp_params param;
/* FIXME - Verify the fixed fields of the INIT chunk. Also, verify
* the mandatory parameters somewhere here and generate either the
* "Missing mandatory parameter" error or the "Invalid mandatory
* parameter" error. */
* parameter" error.
*/
/* Find unrecognized parameters. */
end = ((uint8_t *)peer_init + ntohs(peer_init->chunk_hdr.length));
for (param.v = peer_init->init_hdr.params;
param.v < end;
param.v += WORD_ROUND(ntohs(param.p->length))) {
sctp_walk_params(param, peer_init, init_hdr.params) {
if (!sctp_verify_param(asoc, param, cid, chunk, err_chk_p))
return 0;
......@@ -1513,7 +1509,7 @@ int sctp_verify_init(const sctp_association_t *asoc,
* 1 - continue with the chunk
*/
int sctp_verify_param(const sctp_association_t *asoc,
sctpParam_t param,
union sctp_params param,
sctp_cid_t cid,
sctp_chunk_t *chunk,
sctp_chunk_t **err_chk_p)
......@@ -1576,7 +1572,7 @@ int sctp_verify_param(const sctp_association_t *asoc,
* 1 - continue with the chunk
*/
int sctp_process_unk_param(const sctp_association_t *asoc,
sctpParam_t param,
union sctp_params param,
sctp_chunk_t *chunk,
sctp_chunk_t **err_chk_p)
{
......@@ -1640,8 +1636,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
sctp_init_chunk_t *peer_init,
int priority)
{
sctpParam_t param;
__u8 *end;
union sctp_params param;
sctp_transport_t *transport;
struct list_head *pos, *temp;
char *cookie;
......@@ -1660,10 +1655,9 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
sctp_assoc_add_peer(asoc, peer_addr, priority);
/* Process the initialization parameters. */
end = ((__u8 *)peer_init + ntohs(peer_init->chunk_hdr.length));
for (param.v = peer_init->init_hdr.params;
param.v < end;
param.v += WORD_ROUND(ntohs(param.p->length))) {
sctp_walk_params(param, peer_init, init_hdr.params) {
if (!sctp_process_param(asoc, param, peer_addr, cid,
priority))
goto clean_up;
......@@ -1753,7 +1747,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
* work we do. In particular, we should not build transport
* structures for the addresses.
*/
int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
int sctp_process_param(sctp_association_t *asoc, union sctp_params param,
const sockaddr_storage_t *peer_addr,
sctp_cid_t cid, int priority)
{
......@@ -1792,7 +1786,7 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
case SCTP_PARAM_COOKIE_PRESERVATIVE:
asoc->cookie_preserve =
ntohl(param.bht->lifespan_increment);
ntohl(param.life->lifespan_increment);
break;
case SCTP_PARAM_HOST_NAME_ADDRESS:
......@@ -1919,11 +1913,8 @@ void sctp_param2sockaddr(sockaddr_storage_t *addr, sctp_addr_param_t *param,
/* Convert an IP address in an SCTP param into a sockaddr_in. */
/* Returns true if a valid conversion was possible. */
int sctp_addr2sockaddr(sctpParam_t p, sockaddr_storage_t *sa)
int sctp_addr2sockaddr(union sctp_params p, sockaddr_storage_t *sa)
{
if (!p.v)
return 0;
switch (p.p->type) {
case SCTP_PARAM_IPV4_ADDRESS:
sa->v4.sin_addr = *((struct in_addr *)&p.v4->addr);
......@@ -1964,7 +1955,7 @@ int ipver2af(__u8 ipver)
}
/* Convert a sockaddr_in to an IP address in an SCTP param.
* Returns len if a valid conversion was possible.
* Returns len if a valid conversion was possible.
*/
int sockaddr2sctp_addr(const sockaddr_storage_t *sa, sctp_addr_param_t *p)
{
......
......@@ -236,8 +236,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep,
chunk->subh.init_hdr = (sctp_inithdr_t *)chunk->skb->data;
/* Tag the variable length parameters. */
chunk->param_hdr.v =
skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
new_asoc = sctp_make_temp_asoc(ep, chunk, GFP_ATOMIC);
if (!new_asoc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment