Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
6cf4b403
Commit
6cf4b403
authored
Apr 21, 2003
by
Jon Grimm
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
6a074a55
deabf854
Changes
21
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
777 additions
and
552 deletions
+777
-552
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+1
-0
include/net/sctp/sm.h
include/net/sctp/sm.h
+43
-53
include/net/sctp/structs.h
include/net/sctp/structs.h
+63
-32
net/sctp/Makefile
net/sctp/Makefile
+1
-1
net/sctp/associola.c
net/sctp/associola.c
+13
-10
net/sctp/bind_addr.c
net/sctp/bind_addr.c
+18
-15
net/sctp/chunk.c
net/sctp/chunk.c
+251
-0
net/sctp/endpointola.c
net/sctp/endpointola.c
+2
-2
net/sctp/input.c
net/sctp/input.c
+3
-3
net/sctp/inqueue.c
net/sctp/inqueue.c
+9
-9
net/sctp/ipv6.c
net/sctp/ipv6.c
+1
-1
net/sctp/objcnt.c
net/sctp/objcnt.c
+2
-0
net/sctp/output.c
net/sctp/output.c
+21
-17
net/sctp/outqueue.c
net/sctp/outqueue.c
+56
-46
net/sctp/protocol.c
net/sctp/protocol.c
+1
-1
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+142
-226
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+10
-10
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+87
-87
net/sctp/socket.c
net/sctp/socket.c
+48
-35
net/sctp/ulpevent.c
net/sctp/ulpevent.c
+4
-3
net/sctp/ulpqueue.c
net/sctp/ulpqueue.c
+1
-1
No files found.
include/net/sctp/sctp.h
View file @
6cf4b403
...
@@ -277,6 +277,7 @@ extern atomic_t sctp_dbg_objcnt_chunk;
...
@@ -277,6 +277,7 @@ extern atomic_t sctp_dbg_objcnt_chunk;
extern
atomic_t
sctp_dbg_objcnt_bind_addr
;
extern
atomic_t
sctp_dbg_objcnt_bind_addr
;
extern
atomic_t
sctp_dbg_objcnt_addr
;
extern
atomic_t
sctp_dbg_objcnt_addr
;
extern
atomic_t
sctp_dbg_objcnt_ssnmap
;
extern
atomic_t
sctp_dbg_objcnt_ssnmap
;
extern
atomic_t
sctp_dbg_objcnt_datamsg
;
/* Macros to atomically increment/decrement objcnt counters. */
/* Macros to atomically increment/decrement objcnt counters. */
#define SCTP_DBG_OBJCNT_INC(name) \
#define SCTP_DBG_OBJCNT_INC(name) \
...
...
include/net/sctp/sm.h
View file @
6cf4b403
...
@@ -6,10 +6,6 @@
...
@@ -6,10 +6,6 @@
*
*
* This file is part of the SCTP kernel reference Implementation
* This file is part of the SCTP kernel reference Implementation
*
*
* This file is part of the implementation of the add-IP extension,
* based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001,
* for the SCTP kernel reference Implementation.
*
* These are definitions needed by the state machine.
* These are definitions needed by the state machine.
*
*
* The SCTP reference implementation is free software;
* The SCTP reference implementation is free software;
...
@@ -50,7 +46,6 @@
...
@@ -50,7 +46,6 @@
* be incorporated into the next SCTP release.
* be incorporated into the next SCTP release.
*/
*/
#include <linux/types.h>
#include <linux/types.h>
#include <linux/compiler.h>
#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/slab.h>
...
@@ -209,71 +204,66 @@ __u32 sctp_generate_verification_tag(void);
...
@@ -209,71 +204,66 @@ __u32 sctp_generate_verification_tag(void);
void
sctp_populate_tie_tags
(
__u8
*
cookie
,
__u32
curTag
,
__u32
hisTag
);
void
sctp_populate_tie_tags
(
__u8
*
cookie
,
__u32
curTag
,
__u32
hisTag
);
/* Prototypes for chunk-building functions. */
/* Prototypes for chunk-building functions. */
s
ctp_chunk_t
*
sctp_make_init
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_init
(
const
struct
sctp_association
*
,
const
s
ctp_bind_addr_t
*
,
const
s
truct
sctp_bind_addr
*
,
int
gfp
,
int
vparam_len
);
int
gfp
,
int
vparam_len
);
s
ctp_chunk_t
*
sctp_make_init_ack
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_init_ack
(
const
struct
sctp_association
*
,
const
s
ctp_chunk_t
*
,
const
s
truct
sctp_chunk
*
,
const
int
gfp
,
const
int
gfp
,
const
int
unkparam_len
);
const
int
unkparam_len
);
s
ctp_chunk_t
*
sctp_make_cookie_echo
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_cookie_echo
(
const
struct
sctp_association
*
,
const
s
ctp_chunk_t
*
);
const
s
truct
sctp_chunk
*
);
s
ctp_chunk_t
*
sctp_make_cookie_ack
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_cookie_ack
(
const
struct
sctp_association
*
,
const
s
ctp_chunk_t
*
);
const
s
truct
sctp_chunk
*
);
s
ctp_chunk_t
*
sctp_make_cwr
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_cwr
(
const
struct
sctp_association
*
,
const
__u32
lowest_tsn
,
const
__u32
lowest_tsn
,
const
s
ctp_chunk_t
*
);
const
s
truct
sctp_chunk
*
);
s
ctp_chunk_t
*
sctp_make_datafrag
(
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_datafrag
(
struct
sctp_association
*
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
len
,
const
__u8
*
data
,
int
len
,
const
__u8
*
data
,
__u8
flags
,
__u16
ssn
);
__u8
flags
,
__u16
ssn
);
s
ctp_chunk_t
*
sctp_make_datafrag_empty
(
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_datafrag_empty
(
struct
sctp_association
*
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
len
,
const
__u8
flags
,
int
len
,
const
__u8
flags
,
__u16
ssn
);
__u16
ssn
);
s
ctp_chunk_t
*
sctp_make_data
(
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_data
(
struct
sctp_association
*
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
len
,
const
__u8
*
data
);
int
len
,
const
__u8
*
data
);
s
ctp_chunk_t
*
sctp_make_data_empty
(
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_data_empty
(
struct
sctp_association
*
,
const
struct
sctp_sndrcvinfo
*
,
int
len
);
const
struct
sctp_sndrcvinfo
*
,
int
len
);
s
ctp_chunk_t
*
sctp_make_ecne
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_ecne
(
const
struct
sctp_association
*
,
const
__u32
);
const
__u32
);
s
ctp_chunk_t
*
sctp_make_sack
(
const
struct
sctp_association
*
);
s
truct
sctp_chunk
*
sctp_make_sack
(
const
struct
sctp_association
*
);
s
ctp_chunk_t
*
sctp_make_shutdown
(
const
struct
sctp_association
*
asoc
);
s
truct
sctp_chunk
*
sctp_make_shutdown
(
const
struct
sctp_association
*
asoc
);
s
ctp_chunk_t
*
sctp_make_shutdown_ack
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_shutdown_ack
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
);
const
s
truct
sctp_chunk
*
);
s
ctp_chunk_t
*
sctp_make_shutdown_complete
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_shutdown_complete
(
const
struct
sctp_association
*
,
const
s
ctp_chunk_t
*
);
const
s
truct
sctp_chunk
*
);
void
sctp_init_cause
(
s
ctp_chunk_t
*
,
__u16
cause
,
const
void
*
,
size_t
);
void
sctp_init_cause
(
s
truct
sctp_chunk
*
,
__u16
cause
,
const
void
*
,
size_t
);
s
ctp_chunk_t
*
sctp_make_abort
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_abort
(
const
struct
sctp_association
*
,
const
s
ctp_chunk_t
*
,
const
s
truct
sctp_chunk
*
,
const
size_t
hint
);
const
size_t
hint
);
s
ctp_chunk_t
*
sctp_make_abort_no_data
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_abort_no_data
(
const
struct
sctp_association
*
,
const
s
ctp_chunk_t
*
,
const
s
truct
sctp_chunk
*
,
__u32
tsn
);
__u32
tsn
);
s
ctp_chunk_t
*
sctp_make_abort_user
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_abort_user
(
const
struct
sctp_association
*
,
const
s
ctp_chunk_t
*
,
const
s
truct
sctp_chunk
*
,
const
struct
msghdr
*
);
const
struct
msghdr
*
);
s
ctp_chunk_t
*
sctp_make_heartbeat
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_heartbeat
(
const
struct
sctp_association
*
,
const
struct
sctp_transport
*
,
const
struct
sctp_transport
*
,
const
void
*
payload
,
const
void
*
payload
,
const
size_t
paylen
);
const
size_t
paylen
);
s
ctp_chunk_t
*
sctp_make_heartbeat_ack
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_heartbeat_ack
(
const
struct
sctp_association
*
,
const
s
ctp_chunk_t
*
,
const
s
truct
sctp_chunk
*
,
const
void
*
payload
,
const
void
*
payload
,
const
size_t
paylen
);
const
size_t
paylen
);
s
ctp_chunk_t
*
sctp_make_op_error
(
const
struct
sctp_association
*
,
s
truct
sctp_chunk
*
sctp_make_op_error
(
const
struct
sctp_association
*
,
const
s
ctp_chunk_t
*
chunk
,
const
s
truct
sctp_chunk
*
chunk
,
__u16
cause_code
,
__u16
cause_code
,
const
void
*
payload
,
const
void
*
payload
,
size_t
paylen
);
size_t
paylen
);
void
sctp_chunk_assign_tsn
(
sctp_chunk_t
*
);
void
sctp_chunk_assign_tsn
(
struct
sctp_chunk
*
);
void
sctp_chunk_assign_ssn
(
sctp_chunk_t
*
);
void
sctp_chunk_assign_ssn
(
struct
sctp_chunk
*
);
int
sctp_datachunks_from_user
(
struct
sctp_association
*
,
const
struct
sctp_sndrcvinfo
*
,
struct
msghdr
*
,
int
len
,
struct
sk_buff_head
*
);
/* Prototypes for statetable processing. */
/* Prototypes for statetable processing. */
...
@@ -306,12 +296,12 @@ sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
...
@@ -306,12 +296,12 @@ sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
int
sctp_gen_sack
(
struct
sctp_association
*
,
int
force
,
sctp_cmd_seq_t
*
);
int
sctp_gen_sack
(
struct
sctp_association
*
,
int
force
,
sctp_cmd_seq_t
*
);
void
sctp_do_TSNdup
(
struct
sctp_association
*
,
s
ctp_chunk_t
*
,
long
gap
);
void
sctp_do_TSNdup
(
struct
sctp_association
*
,
s
truct
sctp_chunk
*
,
long
gap
);
void
sctp_generate_t3_rtx_event
(
unsigned
long
peer
);
void
sctp_generate_t3_rtx_event
(
unsigned
long
peer
);
void
sctp_generate_heartbeat_event
(
unsigned
long
peer
);
void
sctp_generate_heartbeat_event
(
unsigned
long
peer
);
sctp_sackhdr_t
*
sctp_sm_pull_sack
(
s
ctp_chunk_t
*
);
sctp_sackhdr_t
*
sctp_sm_pull_sack
(
s
truct
sctp_chunk
*
);
struct
sctp_packet
*
sctp_abort_pkt_new
(
const
struct
sctp_endpoint
*
,
struct
sctp_packet
*
sctp_abort_pkt_new
(
const
struct
sctp_endpoint
*
,
const
struct
sctp_association
*
,
const
struct
sctp_association
*
,
struct
sctp_chunk
*
chunk
,
struct
sctp_chunk
*
chunk
,
...
@@ -327,15 +317,15 @@ sctp_pack_cookie(const struct sctp_endpoint *, const struct sctp_association *,
...
@@ -327,15 +317,15 @@ sctp_pack_cookie(const struct sctp_endpoint *, const struct sctp_association *,
const
__u8
*
,
int
addrs_len
);
const
__u8
*
,
int
addrs_len
);
struct
sctp_association
*
sctp_unpack_cookie
(
const
struct
sctp_endpoint
*
,
struct
sctp_association
*
sctp_unpack_cookie
(
const
struct
sctp_endpoint
*
,
const
struct
sctp_association
*
,
const
struct
sctp_association
*
,
s
ctp_chunk_t
*
,
int
gfp
,
int
*
err
,
s
truct
sctp_chunk
*
,
int
gfp
,
int
*
err
,
s
ctp_chunk_t
**
err_chk_p
);
s
truct
sctp_chunk
**
err_chk_p
);
int
sctp_addip_addr_config
(
struct
sctp_association
*
,
sctp_param_t
,
int
sctp_addip_addr_config
(
struct
sctp_association
*
,
sctp_param_t
,
struct
sockaddr_storage
*
,
int
);
struct
sockaddr_storage
*
,
int
);
void
sctp_send_stale_cookie_err
(
const
struct
sctp_endpoint
*
ep
,
void
sctp_send_stale_cookie_err
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
,
const
s
truct
sctp_chunk
*
chunk
,
sctp_cmd_seq_t
*
commands
,
sctp_cmd_seq_t
*
commands
,
s
ctp_chunk_t
*
err_chunk
);
s
truct
sctp_chunk
*
err_chunk
);
/* 3rd level prototypes */
/* 3rd level prototypes */
__u32
sctp_generate_tag
(
const
struct
sctp_endpoint
*
);
__u32
sctp_generate_tag
(
const
struct
sctp_endpoint
*
);
...
@@ -361,7 +351,7 @@ extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES];
...
@@ -361,7 +351,7 @@ extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES];
/* Get the size of a DATA chunk payload. */
/* Get the size of a DATA chunk payload. */
static
inline
__u16
sctp_data_size
(
s
ctp_chunk_t
*
chunk
)
static
inline
__u16
sctp_data_size
(
s
truct
sctp_chunk
*
chunk
)
{
{
__u16
size
;
__u16
size
;
...
@@ -449,7 +439,7 @@ static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_a
...
@@ -449,7 +439,7 @@ static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_a
* tag and the T bit is set in the Chunk Flags.
* tag and the T bit is set in the Chunk Flags.
*/
*/
static
inline
int
static
inline
int
sctp_vtag_verify_either
(
const
s
ctp_chunk_t
*
chunk
,
sctp_vtag_verify_either
(
const
s
truct
sctp_chunk
*
chunk
,
const
struct
sctp_association
*
asoc
)
const
struct
sctp_association
*
asoc
)
{
{
/* RFC 2960 Section 8.5.1, sctpimpguide-06 Section 2.13.2
/* RFC 2960 Section 8.5.1, sctpimpguide-06 Section 2.13.2
...
...
include/net/sctp/structs.h
View file @
6cf4b403
...
@@ -70,7 +70,6 @@ union sctp_addr {
...
@@ -70,7 +70,6 @@ union sctp_addr {
struct
sockaddr
sa
;
struct
sockaddr
sa
;
};
};
/* Forward declarations for data structures. */
/* Forward declarations for data structures. */
struct
sctp_protocol
;
struct
sctp_protocol
;
struct
sctp_endpoint
;
struct
sctp_endpoint
;
...
@@ -86,8 +85,6 @@ struct sctp_opt;
...
@@ -86,8 +85,6 @@ struct sctp_opt;
struct
sctp_ep_common
;
struct
sctp_ep_common
;
struct
sctp_ssnmap
;
struct
sctp_ssnmap
;
typedef
struct
sctp_chunk
sctp_chunk_t
;
typedef
struct
sctp_bind_addr
sctp_bind_addr_t
;
#include <net/sctp/tsnmap.h>
#include <net/sctp/tsnmap.h>
#include <net/sctp/ulpevent.h>
#include <net/sctp/ulpevent.h>
...
@@ -450,6 +447,29 @@ static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
...
@@ -450,6 +447,29 @@ static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
return
stream
->
ssn
[
id
]
++
;
return
stream
->
ssn
[
id
]
++
;
}
}
/* Structure to track chunk fragments that have been acked, but peer
* fragments of the same message have not.
*/
struct
sctp_datamsg
{
/* Chunks waiting to be submitted to lower layer. */
struct
list_head
chunks
;
/* Chunks that have been transmitted. */
struct
list_head
track
;
/* Reference counting. */
atomic_t
refcnt
;
/* Have the SEND_FAILED notifications been done. */
__u8
notify_done
;
};
struct
sctp_datamsg
*
sctp_datamsg_from_user
(
struct
sctp_association
*
,
struct
sctp_sndrcvinfo
*
,
struct
msghdr
*
,
int
len
);
struct
sctp_datamsg
*
sctp_datamsg_new
(
int
gfp
);
void
sctp_datamsg_put
(
struct
sctp_datamsg
*
);
void
sctp_datamsg_hold
(
struct
sctp_datamsg
*
);
void
sctp_datamsg_free
(
struct
sctp_datamsg
*
);
void
sctp_datamsg_track
(
struct
sctp_chunk
*
);
void
sctp_datamsg_assign
(
struct
sctp_datamsg
*
,
struct
sctp_chunk
*
);
/* RFC2960 1.4 Key Terms
/* RFC2960 1.4 Key Terms
*
*
...
@@ -464,9 +484,10 @@ struct sctp_chunk {
...
@@ -464,9 +484,10 @@ struct sctp_chunk {
* three elements of struct sk_buff. This allows us to reuse
* three elements of struct sk_buff. This allows us to reuse
* all the skb_* queue management functions.
* all the skb_* queue management functions.
*/
*/
s
ctp_chunk_t
*
next
;
s
truct
sctp_chunk
*
next
;
s
ctp_chunk_t
*
prev
;
s
truct
sctp_chunk
*
prev
;
struct
sk_buff_head
*
list
;
struct
sk_buff_head
*
list
;
atomic_t
refcnt
;
/* This is our link to the per-transport transmitted list. */
/* This is our link to the per-transport transmitted list. */
struct
list_head
transmitted_list
;
struct
list_head
transmitted_list
;
...
@@ -522,7 +543,7 @@ struct sctp_chunk {
...
@@ -522,7 +543,7 @@ struct sctp_chunk {
unsigned
long
sent_at
;
unsigned
long
sent_at
;
__u8
rtt_in_progress
;
/* Is this chunk used for RTT calculation? */
__u8
rtt_in_progress
;
/* Is this chunk used for RTT calculation? */
__u8
num_times_sent
;
/* How man times did we send this?
*/
__u8
resent
;
/* Has this chunk ever been retransmitted.
*/
__u8
has_tsn
;
/* Does this chunk have a TSN yet? */
__u8
has_tsn
;
/* Does this chunk have a TSN yet? */
__u8
has_ssn
;
/* Does this chunk have a SSN yet? */
__u8
has_ssn
;
/* Does this chunk have a SSN yet? */
__u8
singleton
;
/* Was this the only chunk in the packet? */
__u8
singleton
;
/* Was this the only chunk in the packet? */
...
@@ -538,6 +559,9 @@ struct sctp_chunk {
...
@@ -538,6 +559,9 @@ struct sctp_chunk {
/* Destination address for this chunk. */
/* Destination address for this chunk. */
union
sctp_addr
dest
;
union
sctp_addr
dest
;
/* For outbound message, track all fragments for SEND_FAILED. */
struct
sctp_datamsg
*
msg
;
/* For an inbound chunk, this tells us where it came from.
/* For an inbound chunk, this tells us where it came from.
* For an outbound chunk, it tells us where we'd like it to
* For an outbound chunk, it tells us where we'd like it to
* go. It is NULL if we have no preference.
* go. It is NULL if we have no preference.
...
@@ -545,14 +569,20 @@ struct sctp_chunk {
...
@@ -545,14 +569,20 @@ struct sctp_chunk {
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
};
};
sctp_chunk_t
*
sctp_make_chunk
(
const
struct
sctp_association
*
,
__u8
type
,
void
sctp_chunk_hold
(
struct
sctp_chunk
*
);
void
sctp_chunk_put
(
struct
sctp_chunk
*
);
int
sctp_user_addto_chunk
(
struct
sctp_chunk
*
chunk
,
int
off
,
int
len
,
struct
iovec
*
data
);
struct
sctp_chunk
*
sctp_make_chunk
(
const
struct
sctp_association
*
,
__u8
type
,
__u8
flags
,
int
size
);
__u8
flags
,
int
size
);
void
sctp_free_chunk
(
sctp_chunk_t
*
);
void
sctp_chunk_free
(
struct
sctp_chunk
*
);
void
*
sctp_addto_chunk
(
sctp_chunk_t
*
chunk
,
int
len
,
const
void
*
data
);
void
*
sctp_addto_chunk
(
struct
sctp_chunk
*
,
int
len
,
const
void
*
data
);
sctp_chunk_t
*
sctp_chunkify
(
struct
sk_buff
*
,
const
struct
sctp_association
*
,
struct
sctp_chunk
*
sctp_chunkify
(
struct
sk_buff
*
,
const
struct
sctp_association
*
,
struct
sock
*
);
struct
sock
*
);
void
sctp_init_addrs
(
sctp_chunk_t
*
,
union
sctp_addr
*
,
union
sctp_addr
*
);
void
sctp_init_addrs
(
struct
sctp_chunk
*
,
union
sctp_addr
*
,
const
union
sctp_addr
*
sctp_source
(
const
sctp_chunk_t
*
chunk
);
union
sctp_addr
*
);
const
union
sctp_addr
*
sctp_source
(
const
struct
sctp_chunk
*
chunk
);
/* This is a structure for holding either an IPv6 or an IPv4 address. */
/* This is a structure for holding either an IPv6 or an IPv4 address. */
/* sin_family -- AF_INET or AF_INET6
/* sin_family -- AF_INET or AF_INET6
...
@@ -564,7 +594,7 @@ struct sockaddr_storage_list {
...
@@ -564,7 +594,7 @@ struct sockaddr_storage_list {
union
sctp_addr
a
;
union
sctp_addr
a
;
};
};
typedef
s
ctp_chunk_t
*
(
sctp_packet_phandler_t
)(
struct
sctp_association
*
);
typedef
s
truct
sctp_chunk
*
(
sctp_packet_phandler_t
)(
struct
sctp_association
*
);
/* This structure holds lists of chunks as we are assembling for
/* This structure holds lists of chunks as we are assembling for
* transmission.
* transmission.
...
@@ -621,7 +651,7 @@ typedef struct sctp_packet *(sctp_outq_ohandler_config_t)
...
@@ -621,7 +651,7 @@ typedef struct sctp_packet *(sctp_outq_ohandler_config_t)
int
ecn_capable
,
int
ecn_capable
,
sctp_packet_phandler_t
*
get_prepend_chunk
);
sctp_packet_phandler_t
*
get_prepend_chunk
);
typedef
sctp_xmit_t
(
sctp_outq_ohandler_t
)(
struct
sctp_packet
*
,
typedef
sctp_xmit_t
(
sctp_outq_ohandler_t
)(
struct
sctp_packet
*
,
s
ctp_chunk_t
*
);
s
truct
sctp_chunk
*
);
typedef
int
(
sctp_outq_ohandler_force_t
)(
struct
sctp_packet
*
);
typedef
int
(
sctp_outq_ohandler_force_t
)(
struct
sctp_packet
*
);
sctp_outq_ohandler_init_t
sctp_packet_init
;
sctp_outq_ohandler_init_t
sctp_packet_init
;
...
@@ -832,7 +862,7 @@ struct sctp_inq {
...
@@ -832,7 +862,7 @@ struct sctp_inq {
/* This is the packet which is currently off the in queue and is
/* This is the packet which is currently off the in queue and is
* being worked on through the inbound chunk processing.
* being worked on through the inbound chunk processing.
*/
*/
s
ctp_chunk_t
*
in_progress
;
s
truct
sctp_chunk
*
in_progress
;
/* This is the delayed task to finish delivering inbound
/* This is the delayed task to finish delivering inbound
* messages.
* messages.
...
@@ -845,7 +875,7 @@ struct sctp_inq {
...
@@ -845,7 +875,7 @@ struct sctp_inq {
struct
sctp_inq
*
sctp_inq_new
(
void
);
struct
sctp_inq
*
sctp_inq_new
(
void
);
void
sctp_inq_init
(
struct
sctp_inq
*
);
void
sctp_inq_init
(
struct
sctp_inq
*
);
void
sctp_inq_free
(
struct
sctp_inq
*
);
void
sctp_inq_free
(
struct
sctp_inq
*
);
void
sctp_inq_push
(
struct
sctp_inq
*
,
s
ctp_chunk_t
*
packet
);
void
sctp_inq_push
(
struct
sctp_inq
*
,
s
truct
sctp_chunk
*
packet
);
struct
sctp_chunk
*
sctp_inq_pop
(
struct
sctp_inq
*
);
struct
sctp_chunk
*
sctp_inq_pop
(
struct
sctp_inq
*
);
void
sctp_inq_set_th_handler
(
struct
sctp_inq
*
,
void
(
*
)(
void
*
),
void
*
);
void
sctp_inq_set_th_handler
(
struct
sctp_inq
*
,
void
(
*
)(
void
*
),
void
*
);
...
@@ -916,7 +946,7 @@ struct sctp_outq *sctp_outq_new(struct sctp_association *);
...
@@ -916,7 +946,7 @@ struct sctp_outq *sctp_outq_new(struct sctp_association *);
void
sctp_outq_init
(
struct
sctp_association
*
,
struct
sctp_outq
*
);
void
sctp_outq_init
(
struct
sctp_association
*
,
struct
sctp_outq
*
);
void
sctp_outq_teardown
(
struct
sctp_outq
*
);
void
sctp_outq_teardown
(
struct
sctp_outq
*
);
void
sctp_outq_free
(
struct
sctp_outq
*
);
void
sctp_outq_free
(
struct
sctp_outq
*
);
int
sctp_outq_tail
(
struct
sctp_outq
*
,
s
ctp_chunk_t
*
chunk
);
int
sctp_outq_tail
(
struct
sctp_outq
*
,
s
truct
sctp_chunk
*
chunk
);
int
sctp_outq_flush
(
struct
sctp_outq
*
,
int
);
int
sctp_outq_flush
(
struct
sctp_outq
*
,
int
);
int
sctp_outq_sack
(
struct
sctp_outq
*
,
sctp_sackhdr_t
*
);
int
sctp_outq_sack
(
struct
sctp_outq
*
,
sctp_sackhdr_t
*
);
int
sctp_outq_is_empty
(
const
struct
sctp_outq
*
);
int
sctp_outq_is_empty
(
const
struct
sctp_outq
*
);
...
@@ -953,15 +983,16 @@ struct sctp_bind_addr {
...
@@ -953,15 +983,16 @@ struct sctp_bind_addr {
int
malloced
;
/* Are we kfree()able? */
int
malloced
;
/* Are we kfree()able? */
};
};
sctp_bind_addr_t
*
sctp_bind_addr_new
(
int
gfp_mask
);
struct
sctp_bind_addr
*
sctp_bind_addr_new
(
int
gfp_mask
);
void
sctp_bind_addr_init
(
sctp_bind_addr_t
*
,
__u16
port
);
void
sctp_bind_addr_init
(
struct
sctp_bind_addr
*
,
__u16
port
);
void
sctp_bind_addr_free
(
sctp_bind_addr_t
*
);
void
sctp_bind_addr_free
(
struct
sctp_bind_addr
*
);
int
sctp_bind_addr_copy
(
sctp_bind_addr_t
*
dest
,
const
sctp_bind_addr_t
*
src
,
int
sctp_bind_addr_copy
(
struct
sctp_bind_addr
*
dest
,
const
struct
sctp_bind_addr
*
src
,
sctp_scope_t
scope
,
int
gfp
,
int
flags
);
sctp_scope_t
scope
,
int
gfp
,
int
flags
);
int
sctp_add_bind_addr
(
s
ctp_bind_addr_t
*
,
union
sctp_addr
*
,
int
sctp_add_bind_addr
(
s
truct
sctp_bind_addr
*
,
union
sctp_addr
*
,
int
gfp
);
int
gfp
);
int
sctp_del_bind_addr
(
s
ctp_bind_addr_t
*
,
union
sctp_addr
*
);
int
sctp_del_bind_addr
(
s
truct
sctp_bind_addr
*
,
union
sctp_addr
*
);
int
sctp_bind_addr_match
(
s
ctp_bind_addr_t
*
,
const
union
sctp_addr
*
,
int
sctp_bind_addr_match
(
s
truct
sctp_bind_addr
*
,
const
union
sctp_addr
*
,
struct
sctp_opt
*
);
struct
sctp_opt
*
);
union
sctp_params
sctp_bind_addrs_to_raw
(
const
struct
sctp_bind_addr
*
bp
,
union
sctp_params
sctp_bind_addrs_to_raw
(
const
struct
sctp_bind_addr
*
bp
,
int
*
addrs_len
,
int
gfp
);
int
*
addrs_len
,
int
gfp
);
...
@@ -1025,7 +1056,7 @@ struct sctp_ep_common {
...
@@ -1025,7 +1056,7 @@ struct sctp_ep_common {
* bind_addr.port is our shared port number.
* bind_addr.port is our shared port number.
* bind_addr.address_list is our set of local IP addresses.
* bind_addr.address_list is our set of local IP addresses.
*/
*/
s
ctp_bind_addr_t
bind_addr
;
s
truct
sctp_bind_addr
bind_addr
;
/* Protection during address list comparisons. */
/* Protection during address list comparisons. */
rwlock_t
addr_lock
;
rwlock_t
addr_lock
;
...
@@ -1477,7 +1508,7 @@ struct sctp_association {
...
@@ -1477,7 +1508,7 @@ struct sctp_association {
* [This is our one-and-only-one ASCONF in flight. If we do
* [This is our one-and-only-one ASCONF in flight. If we do
* not have an ASCONF in flight, this is NULL.]
* not have an ASCONF in flight, this is NULL.]
*/
*/
s
ctp_chunk_t
*
addip_last_asconf
;
s
truct
sctp_chunk
*
addip_last_asconf
;
/* ADDIP Section 4.2 Upon reception of an ASCONF Chunk.
/* ADDIP Section 4.2 Upon reception of an ASCONF Chunk.
*
*
...
@@ -1492,7 +1523,7 @@ struct sctp_association {
...
@@ -1492,7 +1523,7 @@ struct sctp_association {
* [This is our saved ASCONF-ACK. We invalidate it when a new
* [This is our saved ASCONF-ACK. We invalidate it when a new
* ASCONF serial number arrives.]
* ASCONF serial number arrives.]
*/
*/
s
ctp_chunk_t
*
addip_last_asconf_ack
;
s
truct
sctp_chunk
*
addip_last_asconf_ack
;
/* These ASCONF chunks are waiting to be sent.
/* These ASCONF chunks are waiting to be sent.
*
*
...
@@ -1614,8 +1645,8 @@ int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
...
@@ -1614,8 +1645,8 @@ int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
int
sctp_cmp_addr_exact
(
const
union
sctp_addr
*
ss1
,
int
sctp_cmp_addr_exact
(
const
union
sctp_addr
*
ss1
,
const
union
sctp_addr
*
ss2
);
const
union
sctp_addr
*
ss2
);
s
ctp_chunk_t
*
sctp_get_ecne_prepend
(
struct
sctp_association
*
asoc
);
s
truct
sctp_chunk
*
sctp_get_ecne_prepend
(
struct
sctp_association
*
asoc
);
s
ctp_chunk_t
*
sctp_get_no_prepend
(
struct
sctp_association
*
asoc
);
s
truct
sctp_chunk
*
sctp_get_no_prepend
(
struct
sctp_association
*
asoc
);
/* A convenience structure to parse out SCTP specific CMSGs. */
/* A convenience structure to parse out SCTP specific CMSGs. */
typedef
struct
sctp_cmsgs
{
typedef
struct
sctp_cmsgs
{
...
...
net/sctp/Makefile
View file @
6cf4b403
...
@@ -6,7 +6,7 @@ obj-$(CONFIG_IP_SCTP) += sctp.o
...
@@ -6,7 +6,7 @@ obj-$(CONFIG_IP_SCTP) += sctp.o
sctp-y
:=
sm_statetable.o sm_statefuns.o sm_sideeffect.o
\
sctp-y
:=
sm_statetable.o sm_statefuns.o sm_sideeffect.o
\
protocol.o endpointola.o associola.o
\
protocol.o endpointola.o associola.o
\
transport.o sm_make_chunk.o ulpevent.o
\
transport.o
chunk.o
sm_make_chunk.o ulpevent.o
\
inqueue.o outqueue.o ulpqueue.o command.o
\
inqueue.o outqueue.o ulpqueue.o command.o
\
tsnmap.o bind_addr.o socket.o primitive.o
\
tsnmap.o bind_addr.o socket.o primitive.o
\
output.o input.o debug.o ssnmap.o proc.o
output.o input.o debug.o ssnmap.o proc.o
...
...
net/sctp/associola.c
View file @
6cf4b403
...
@@ -664,7 +664,7 @@ int sctp_cmp_addr_exact(const union sctp_addr *ss1,
...
@@ -664,7 +664,7 @@ int sctp_cmp_addr_exact(const union sctp_addr *ss1,
* Note: We are sly and return a shared, prealloced chunk. FIXME:
* Note: We are sly and return a shared, prealloced chunk. FIXME:
* No we don't, but we could/should.
* No we don't, but we could/should.
*/
*/
s
ctp_chunk_t
*
sctp_get_ecne_prepend
(
struct
sctp_association
*
asoc
)
s
truct
sctp_chunk
*
sctp_get_ecne_prepend
(
struct
sctp_association
*
asoc
)
{
{
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
;
...
@@ -682,7 +682,7 @@ sctp_chunk_t *sctp_get_ecne_prepend(struct sctp_association *asoc)
...
@@ -682,7 +682,7 @@ sctp_chunk_t *sctp_get_ecne_prepend(struct sctp_association *asoc)
/* Use this function for the packet prepend callback when no ECNE
/* Use this function for the packet prepend callback when no ECNE
* packet is desired (e.g. some packets don't like to be bundled).
* packet is desired (e.g. some packets don't like to be bundled).
*/
*/
s
ctp_chunk_t
*
sctp_get_no_prepend
(
struct
sctp_association
*
asoc
)
s
truct
sctp_chunk
*
sctp_get_no_prepend
(
struct
sctp_association
*
asoc
)
{
{
return
NULL
;
return
NULL
;
}
}
...
@@ -690,13 +690,14 @@ sctp_chunk_t *sctp_get_no_prepend(struct sctp_association *asoc)
...
@@ -690,13 +690,14 @@ sctp_chunk_t *sctp_get_no_prepend(struct sctp_association *asoc)
/*
/*
* Find which transport this TSN was sent on.
* Find which transport this TSN was sent on.
*/
*/
struct
sctp_transport
*
sctp_assoc_lookup_tsn
(
struct
sctp_association
*
asoc
,
__u32
tsn
)
struct
sctp_transport
*
sctp_assoc_lookup_tsn
(
struct
sctp_association
*
asoc
,
__u32
tsn
)
{
{
struct
sctp_transport
*
active
;
struct
sctp_transport
*
active
;
struct
sctp_transport
*
match
;
struct
sctp_transport
*
match
;
struct
list_head
*
entry
,
*
pos
;
struct
list_head
*
entry
,
*
pos
;
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
__u32
key
=
htonl
(
tsn
);
__u32
key
=
htonl
(
tsn
);
match
=
NULL
;
match
=
NULL
;
...
@@ -719,7 +720,7 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc, __u3
...
@@ -719,7 +720,7 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc, __u3
active
=
asoc
->
peer
.
active_path
;
active
=
asoc
->
peer
.
active_path
;
list_for_each
(
entry
,
&
active
->
transmitted
)
{
list_for_each
(
entry
,
&
active
->
transmitted
)
{
chunk
=
list_entry
(
entry
,
s
ctp_chunk_t
,
transmitted_list
);
chunk
=
list_entry
(
entry
,
s
truct
sctp_chunk
,
transmitted_list
);
if
(
key
==
chunk
->
subh
.
data_hdr
->
tsn
)
{
if
(
key
==
chunk
->
subh
.
data_hdr
->
tsn
)
{
match
=
active
;
match
=
active
;
...
@@ -734,7 +735,7 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc, __u3
...
@@ -734,7 +735,7 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc, __u3
if
(
transport
==
active
)
if
(
transport
==
active
)
break
;
break
;
list_for_each
(
entry
,
&
transport
->
transmitted
)
{
list_for_each
(
entry
,
&
transport
->
transmitted
)
{
chunk
=
list_entry
(
entry
,
s
ctp_chunk_t
,
chunk
=
list_entry
(
entry
,
s
truct
sctp_chunk
,
transmitted_list
);
transmitted_list
);
if
(
key
==
chunk
->
subh
.
data_hdr
->
tsn
)
{
if
(
key
==
chunk
->
subh
.
data_hdr
->
tsn
)
{
match
=
transport
;
match
=
transport
;
...
@@ -776,7 +777,7 @@ struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc,
...
@@ -776,7 +777,7 @@ struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc,
static
void
sctp_assoc_bh_rcv
(
struct
sctp_association
*
asoc
)
static
void
sctp_assoc_bh_rcv
(
struct
sctp_association
*
asoc
)
{
{
struct
sctp_endpoint
*
ep
;
struct
sctp_endpoint
*
ep
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
struct
sock
*
sk
;
struct
sock
*
sk
;
struct
sctp_inq
*
inqueue
;
struct
sctp_inq
*
inqueue
;
int
state
,
subtype
;
int
state
,
subtype
;
...
@@ -852,7 +853,8 @@ void sctp_assoc_migrate(struct sctp_association *assoc, struct sock *newsk)
...
@@ -852,7 +853,8 @@ void sctp_assoc_migrate(struct sctp_association *assoc, struct sock *newsk)
}
}
/* Update an association (possibly from unexpected COOKIE-ECHO processing). */
/* Update an association (possibly from unexpected COOKIE-ECHO processing). */
void
sctp_assoc_update
(
struct
sctp_association
*
asoc
,
struct
sctp_association
*
new
)
void
sctp_assoc_update
(
struct
sctp_association
*
asoc
,
struct
sctp_association
*
new
)
{
{
/* Copy in new parameters of peer. */
/* Copy in new parameters of peer. */
asoc
->
c
=
new
->
c
;
asoc
->
c
=
new
->
c
;
...
@@ -946,7 +948,8 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
...
@@ -946,7 +948,8 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
}
}
/* Choose the transport for sending a SHUTDOWN packet. */
/* Choose the transport for sending a SHUTDOWN packet. */
struct
sctp_transport
*
sctp_assoc_choose_shutdown_transport
(
struct
sctp_association
*
asoc
)
struct
sctp_transport
*
sctp_assoc_choose_shutdown_transport
(
struct
sctp_association
*
asoc
)
{
{
/* If this is the first time SHUTDOWN is sent, use the active path,
/* If this is the first time SHUTDOWN is sent, use the active path,
* else use the retran path. If the last SHUTDOWN was sent over the
* else use the retran path. If the last SHUTDOWN was sent over the
...
@@ -1011,7 +1014,7 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc)
...
@@ -1011,7 +1014,7 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc)
/* Increase asoc's rwnd by len and send any window update SACK if needed. */
/* Increase asoc's rwnd by len and send any window update SACK if needed. */
void
sctp_assoc_rwnd_increase
(
struct
sctp_association
*
asoc
,
int
len
)
void
sctp_assoc_rwnd_increase
(
struct
sctp_association
*
asoc
,
int
len
)
{
{
s
ctp_chunk_t
*
sack
;
s
truct
sctp_chunk
*
sack
;
struct
timer_list
*
timer
;
struct
timer_list
*
timer
;
if
(
asoc
->
rwnd_over
)
{
if
(
asoc
->
rwnd_over
)
{
...
...
net/sctp/bind_addr.c
View file @
6cf4b403
...
@@ -52,16 +52,17 @@
...
@@ -52,16 +52,17 @@
#include <net/sctp/sm.h>
#include <net/sctp/sm.h>
/* Forward declarations for internal helpers. */
/* Forward declarations for internal helpers. */
static
int
sctp_copy_one_addr
(
s
ctp_bind_addr_t
*
,
union
sctp_addr
*
,
static
int
sctp_copy_one_addr
(
s
truct
sctp_bind_addr
*
,
union
sctp_addr
*
,
sctp_scope_t
scope
,
int
gfp
,
int
flags
);
sctp_scope_t
scope
,
int
gfp
,
int
flags
);
static
void
sctp_bind_addr_clean
(
s
ctp_bind_addr_t
*
);
static
void
sctp_bind_addr_clean
(
s
truct
sctp_bind_addr
*
);
/* First Level Abstractions. */
/* First Level Abstractions. */
/* Copy 'src' to 'dest' taking 'scope' into account. Omit addresses
/* Copy 'src' to 'dest' taking 'scope' into account. Omit addresses
* in 'src' which have a broader scope than 'scope'.
* in 'src' which have a broader scope than 'scope'.
*/
*/
int
sctp_bind_addr_copy
(
sctp_bind_addr_t
*
dest
,
const
sctp_bind_addr_t
*
src
,
int
sctp_bind_addr_copy
(
struct
sctp_bind_addr
*
dest
,
const
struct
sctp_bind_addr
*
src
,
sctp_scope_t
scope
,
int
gfp
,
int
flags
)
sctp_scope_t
scope
,
int
gfp
,
int
flags
)
{
{
struct
sockaddr_storage_list
*
addr
;
struct
sockaddr_storage_list
*
addr
;
...
@@ -104,11 +105,11 @@ int sctp_bind_addr_copy(sctp_bind_addr_t *dest, const sctp_bind_addr_t *src,
...
@@ -104,11 +105,11 @@ int sctp_bind_addr_copy(sctp_bind_addr_t *dest, const sctp_bind_addr_t *src,
}
}
/* Create a new SCTP_bind_addr from nothing. */
/* Create a new SCTP_bind_addr from nothing. */
s
ctp_bind_addr_t
*
sctp_bind_addr_new
(
int
gfp
)
s
truct
sctp_bind_addr
*
sctp_bind_addr_new
(
int
gfp
)
{
{
s
ctp_bind_addr_t
*
retval
;
s
truct
sctp_bind_addr
*
retval
;
retval
=
t_new
(
s
ctp_bind_addr_t
,
gfp
);
retval
=
t_new
(
s
truct
sctp_bind_addr
,
gfp
);
if
(
!
retval
)
if
(
!
retval
)
goto
nomem
;
goto
nomem
;
...
@@ -123,7 +124,7 @@ sctp_bind_addr_t *sctp_bind_addr_new(int gfp)
...
@@ -123,7 +124,7 @@ sctp_bind_addr_t *sctp_bind_addr_new(int gfp)
/* Initialize the SCTP_bind_addr structure for either an endpoint or
/* Initialize the SCTP_bind_addr structure for either an endpoint or
* an association.
* an association.
*/
*/
void
sctp_bind_addr_init
(
s
ctp_bind_addr_t
*
bp
,
__u16
port
)
void
sctp_bind_addr_init
(
s
truct
sctp_bind_addr
*
bp
,
__u16
port
)
{
{
bp
->
malloced
=
0
;
bp
->
malloced
=
0
;
...
@@ -132,7 +133,7 @@ void sctp_bind_addr_init(sctp_bind_addr_t *bp, __u16 port)
...
@@ -132,7 +133,7 @@ void sctp_bind_addr_init(sctp_bind_addr_t *bp, __u16 port)
}
}
/* Dispose of the address list. */
/* Dispose of the address list. */
static
void
sctp_bind_addr_clean
(
s
ctp_bind_addr_t
*
bp
)
static
void
sctp_bind_addr_clean
(
s
truct
sctp_bind_addr
*
bp
)
{
{
struct
sockaddr_storage_list
*
addr
;
struct
sockaddr_storage_list
*
addr
;
struct
list_head
*
pos
,
*
temp
;
struct
list_head
*
pos
,
*
temp
;
...
@@ -147,7 +148,7 @@ static void sctp_bind_addr_clean(sctp_bind_addr_t *bp)
...
@@ -147,7 +148,7 @@ static void sctp_bind_addr_clean(sctp_bind_addr_t *bp)
}
}
/* Dispose of an SCTP_bind_addr structure */
/* Dispose of an SCTP_bind_addr structure */
void
sctp_bind_addr_free
(
s
ctp_bind_addr_t
*
bp
)
void
sctp_bind_addr_free
(
s
truct
sctp_bind_addr
*
bp
)
{
{
/* Empty the bind address list. */
/* Empty the bind address list. */
sctp_bind_addr_clean
(
bp
);
sctp_bind_addr_clean
(
bp
);
...
@@ -159,7 +160,7 @@ void sctp_bind_addr_free(sctp_bind_addr_t *bp)
...
@@ -159,7 +160,7 @@ void sctp_bind_addr_free(sctp_bind_addr_t *bp)
}
}
/* Add an address to the bind address list in the SCTP_bind_addr structure. */
/* Add an address to the bind address list in the SCTP_bind_addr structure. */
int
sctp_add_bind_addr
(
s
ctp_bind_addr_t
*
bp
,
union
sctp_addr
*
new
,
int
sctp_add_bind_addr
(
s
truct
sctp_bind_addr
*
bp
,
union
sctp_addr
*
new
,
int
gfp
)
int
gfp
)
{
{
struct
sockaddr_storage_list
*
addr
;
struct
sockaddr_storage_list
*
addr
;
...
@@ -187,7 +188,7 @@ int sctp_add_bind_addr(sctp_bind_addr_t *bp, union sctp_addr *new,
...
@@ -187,7 +188,7 @@ int sctp_add_bind_addr(sctp_bind_addr_t *bp, union sctp_addr *new,
/* Delete an address from the bind address list in the SCTP_bind_addr
/* Delete an address from the bind address list in the SCTP_bind_addr
* structure.
* structure.
*/
*/
int
sctp_del_bind_addr
(
s
ctp_bind_addr_t
*
bp
,
union
sctp_addr
*
del_addr
)
int
sctp_del_bind_addr
(
s
truct
sctp_bind_addr
*
bp
,
union
sctp_addr
*
del_addr
)
{
{
struct
list_head
*
pos
,
*
temp
;
struct
list_head
*
pos
,
*
temp
;
struct
sockaddr_storage_list
*
addr
;
struct
sockaddr_storage_list
*
addr
;
...
@@ -212,7 +213,7 @@ int sctp_del_bind_addr(sctp_bind_addr_t *bp, union sctp_addr *del_addr)
...
@@ -212,7 +213,7 @@ int sctp_del_bind_addr(sctp_bind_addr_t *bp, union sctp_addr *del_addr)
*
*
* The second argument is the return value for the length.
* The second argument is the return value for the length.
*/
*/
union
sctp_params
sctp_bind_addrs_to_raw
(
const
s
ctp_bind_addr_t
*
bp
,
union
sctp_params
sctp_bind_addrs_to_raw
(
const
s
truct
sctp_bind_addr
*
bp
,
int
*
addrs_len
,
int
gfp
)
int
*
addrs_len
,
int
gfp
)
{
{
union
sctp_params
addrparms
;
union
sctp_params
addrparms
;
...
@@ -261,7 +262,7 @@ union sctp_params sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp,
...
@@ -261,7 +262,7 @@ union sctp_params sctp_bind_addrs_to_raw(const sctp_bind_addr_t *bp,
* Create an address list out of the raw address list format (IPv4 and IPv6
* Create an address list out of the raw address list format (IPv4 and IPv6
* address parameters).
* address parameters).
*/
*/
int
sctp_raw_to_bind_addrs
(
s
ctp_bind_addr_t
*
bp
,
__u8
*
raw_addr_list
,
int
sctp_raw_to_bind_addrs
(
s
truct
sctp_bind_addr
*
bp
,
__u8
*
raw_addr_list
,
int
addrs_len
,
__u16
port
,
int
gfp
)
int
addrs_len
,
__u16
port
,
int
gfp
)
{
{
sctp_addr_param_t
*
rawaddr
;
sctp_addr_param_t
*
rawaddr
;
...
@@ -307,7 +308,8 @@ int sctp_raw_to_bind_addrs(sctp_bind_addr_t *bp, __u8 *raw_addr_list,
...
@@ -307,7 +308,8 @@ int sctp_raw_to_bind_addrs(sctp_bind_addr_t *bp, __u8 *raw_addr_list,
********************************************************************/
********************************************************************/
/* Does this contain a specified address? Allow wildcarding. */
/* Does this contain a specified address? Allow wildcarding. */
int
sctp_bind_addr_match
(
sctp_bind_addr_t
*
bp
,
const
union
sctp_addr
*
addr
,
int
sctp_bind_addr_match
(
struct
sctp_bind_addr
*
bp
,
const
union
sctp_addr
*
addr
,
struct
sctp_opt
*
opt
)
struct
sctp_opt
*
opt
)
{
{
struct
sockaddr_storage_list
*
laddr
;
struct
sockaddr_storage_list
*
laddr
;
...
@@ -323,7 +325,8 @@ int sctp_bind_addr_match(sctp_bind_addr_t *bp, const union sctp_addr *addr,
...
@@ -323,7 +325,8 @@ int sctp_bind_addr_match(sctp_bind_addr_t *bp, const union sctp_addr *addr,
}
}
/* Copy out addresses from the global local address list. */
/* Copy out addresses from the global local address list. */
static
int
sctp_copy_one_addr
(
sctp_bind_addr_t
*
dest
,
union
sctp_addr
*
addr
,
static
int
sctp_copy_one_addr
(
struct
sctp_bind_addr
*
dest
,
union
sctp_addr
*
addr
,
sctp_scope_t
scope
,
int
gfp
,
int
flags
)
sctp_scope_t
scope
,
int
gfp
,
int
flags
)
{
{
struct
sctp_protocol
*
proto
=
sctp_get_protocol
();
struct
sctp_protocol
*
proto
=
sctp_get_protocol
();
...
...
net/sctp/chunk.c
0 → 100644
View file @
6cf4b403
/* SCTP kernel reference Implementation
* Copyright (c) 2003 International Business Machines Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
* This file contains the code relating the the chunk abstraction.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Jon Grimm <jgrimm@us.ibm.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/net.h>
#include <linux/inet.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
/* This file is mostly in anticipation of future work, but initially
* populate with fragment tracking for an outbound message.
*/
/* Initialize datamsg from memory. */
void
sctp_datamsg_init
(
struct
sctp_datamsg
*
msg
)
{
atomic_set
(
&
msg
->
refcnt
,
1
);
msg
->
notify_done
=
0
;
INIT_LIST_HEAD
(
&
msg
->
chunks
);
INIT_LIST_HEAD
(
&
msg
->
track
);
}
/* Allocate and initialize datamsg. */
struct
sctp_datamsg
*
sctp_datamsg_new
(
int
gfp
)
{
struct
sctp_datamsg
*
msg
;
msg
=
kmalloc
(
sizeof
(
struct
sctp_datamsg
),
gfp
);
if
(
msg
)
sctp_datamsg_init
(
msg
);
SCTP_DBG_OBJCNT_INC
(
datamsg
);
return
msg
;
}
/* Final destructruction of datamsg memory. */
static
void
sctp_datamsg_destroy
(
struct
sctp_datamsg
*
msg
)
{
struct
list_head
*
pos
,
*
temp
;
struct
sctp_chunk
*
chunk
;
/* Release all references, if there are any left. */
list_for_each_safe
(
pos
,
temp
,
&
msg
->
track
)
{
list_del
(
pos
);
chunk
=
list_entry
(
pos
,
struct
sctp_chunk
,
frag_list
);
sctp_chunk_put
(
chunk
);
}
SCTP_DBG_OBJCNT_DEC
(
datamsg
);
kfree
(
msg
);
}
/* Hold a reference. */
void
sctp_datamsg_hold
(
struct
sctp_datamsg
*
msg
)
{
atomic_inc
(
&
msg
->
refcnt
);
}
/* Release a reference. */
void
sctp_datamsg_put
(
struct
sctp_datamsg
*
msg
)
{
if
(
atomic_dec_and_test
(
&
msg
->
refcnt
))
sctp_datamsg_destroy
(
msg
);
}
/* Free a message. Really just give up a reference, the
* really free happens in sctp_datamsg_destroy().
*/
void
sctp_datamsg_free
(
struct
sctp_datamsg
*
msg
)
{
sctp_datamsg_put
(
msg
);
}
/* Hold on to all the fragments until all chunks have been sent. */
void
sctp_datamsg_track
(
struct
sctp_chunk
*
chunk
)
{
sctp_chunk_hold
(
chunk
);
list_add_tail
(
&
chunk
->
frag_list
,
&
chunk
->
msg
->
track
);
}
/* Assign a chunk to this datamsg. */
void
sctp_datamsg_assign
(
struct
sctp_datamsg
*
msg
,
struct
sctp_chunk
*
chunk
)
{
sctp_datamsg_hold
(
msg
);
chunk
->
msg
=
msg
;
}
/* A data chunk can have a maximum payload of (2^16 - 20). Break
* down any such message into smaller chunks. Opportunistically, fragment
* the chunks down to the current MTU constraints. We may get refragmented
* later if the PMTU changes, but it is _much better_ to fragment immediately
* with a reasonable guess than always doing our fragmentation on the
* soft-interrupt.
*/
struct
sctp_datamsg
*
sctp_datamsg_from_user
(
struct
sctp_association
*
asoc
,
struct
sctp_sndrcvinfo
*
sinfo
,
struct
msghdr
*
msgh
,
int
msg_len
)
{
int
max
,
whole
,
i
,
offset
,
over
,
err
;
int
len
,
first_len
;
struct
sctp_chunk
*
chunk
;
struct
sctp_datamsg
*
msg
;
struct
list_head
*
pos
,
*
temp
;
__u8
frag
;
msg
=
sctp_datamsg_new
(
GFP_KERNEL
);
if
(
!
msg
)
return
NULL
;
/* What is a reasonable fragmentation point right now? */
max
=
asoc
->
pmtu
;
if
(
max
<
SCTP_MIN_PMTU
)
max
=
SCTP_MIN_PMTU
;
max
-=
SCTP_IP_OVERHEAD
;
/* Make sure not beyond maximum chunk size. */
if
(
max
>
SCTP_MAX_CHUNK_LEN
)
max
=
SCTP_MAX_CHUNK_LEN
;
/* Subtract out the overhead of a data chunk header. */
max
-=
sizeof
(
struct
sctp_data_chunk
);
whole
=
0
;
first_len
=
max
;
/* Encourage Cookie-ECHO bundling. */
if
(
asoc
->
state
<
SCTP_STATE_COOKIE_ECHOED
)
{
whole
=
msg_len
/
(
max
-
SCTP_ARBITRARY_COOKIE_ECHO_LEN
);
/* Account for the DATA to be bundled with the COOKIE-ECHO. */
if
(
whole
)
{
first_len
=
max
-
SCTP_ARBITRARY_COOKIE_ECHO_LEN
;
msg_len
-=
first_len
;
whole
=
1
;
}
}
/* How many full sized? How many bytes leftover? */
whole
+=
msg_len
/
max
;
over
=
msg_len
%
max
;
offset
=
0
;
if
(
whole
&&
over
)
SCTP_INC_STATS_USER
(
SctpFragUsrMsgs
);
/* Create chunks for all the full sized DATA chunks. */
for
(
i
=
0
,
len
=
first_len
;
i
<
whole
;
i
++
)
{
frag
=
SCTP_DATA_MIDDLE_FRAG
;
if
(
0
==
i
)
frag
|=
SCTP_DATA_FIRST_FRAG
;
if
((
i
==
(
whole
-
1
))
&&
!
over
)
frag
|=
SCTP_DATA_LAST_FRAG
;
chunk
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
len
,
frag
,
0
);
if
(
!
chunk
)
goto
errout
;
err
=
sctp_user_addto_chunk
(
chunk
,
offset
,
len
,
msgh
->
msg_iov
);
if
(
err
<
0
)
goto
errout
;
offset
+=
len
;
/* Put the chunk->skb back into the form expected by send. */
__skb_pull
(
chunk
->
skb
,
(
__u8
*
)
chunk
->
chunk_hdr
-
(
__u8
*
)
chunk
->
skb
->
data
);
sctp_datamsg_assign
(
msg
,
chunk
);
list_add_tail
(
&
chunk
->
frag_list
,
&
msg
->
chunks
);
/* The first chunk, the first chunk was likely short
* to allow bundling, so reset to full size.
*/
if
(
0
==
i
)
len
=
max
;
}
/* .. now the leftover bytes. */
if
(
over
)
{
if
(
!
whole
)
frag
=
SCTP_DATA_NOT_FRAG
;
else
frag
=
SCTP_DATA_LAST_FRAG
;
chunk
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
over
,
frag
,
0
);
if
(
!
chunk
)
goto
errout
;
err
=
sctp_user_addto_chunk
(
chunk
,
offset
,
over
,
msgh
->
msg_iov
);
/* Put the chunk->skb back into the form expected by send. */
__skb_pull
(
chunk
->
skb
,
(
__u8
*
)
chunk
->
chunk_hdr
-
(
__u8
*
)
chunk
->
skb
->
data
);
if
(
err
<
0
)
goto
errout
;
sctp_datamsg_assign
(
msg
,
chunk
);
list_add_tail
(
&
chunk
->
frag_list
,
&
msg
->
chunks
);
}
return
msg
;
errout:
list_for_each_safe
(
pos
,
temp
,
&
msg
->
chunks
)
{
list_del
(
pos
);
chunk
=
list_entry
(
pos
,
struct
sctp_chunk
,
frag_list
);
sctp_chunk_free
(
chunk
);
}
sctp_datamsg_free
(
msg
);
return
NULL
;
}
net/sctp/endpointola.c
View file @
6cf4b403
...
@@ -315,7 +315,7 @@ int sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep,
...
@@ -315,7 +315,7 @@ int sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep,
{
{
struct
list_head
*
pos
;
struct
list_head
*
pos
;
struct
sockaddr_storage_list
*
addr
;
struct
sockaddr_storage_list
*
addr
;
s
ctp_bind_addr_t
*
bp
;
s
truct
sctp_bind_addr
*
bp
;
sctp_read_lock
(
&
ep
->
base
.
addr_lock
);
sctp_read_lock
(
&
ep
->
base
.
addr_lock
);
bp
=
&
ep
->
base
.
bind_addr
;
bp
=
&
ep
->
base
.
bind_addr
;
...
@@ -339,7 +339,7 @@ static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep)
...
@@ -339,7 +339,7 @@ static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep)
struct
sctp_association
*
asoc
;
struct
sctp_association
*
asoc
;
struct
sock
*
sk
;
struct
sock
*
sk
;
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
struct
sctp_inq
*
inqueue
;
struct
sctp_inq
*
inqueue
;
sctp_subtype_t
subtype
;
sctp_subtype_t
subtype
;
sctp_state_t
state
;
sctp_state_t
state
;
...
...
net/sctp/input.c
View file @
6cf4b403
...
@@ -106,7 +106,7 @@ int sctp_rcv(struct sk_buff *skb)
...
@@ -106,7 +106,7 @@ int sctp_rcv(struct sk_buff *skb)
struct
sctp_endpoint
*
ep
=
NULL
;
struct
sctp_endpoint
*
ep
=
NULL
;
struct
sctp_ep_common
*
rcvr
;
struct
sctp_ep_common
*
rcvr
;
struct
sctp_transport
*
transport
=
NULL
;
struct
sctp_transport
*
transport
=
NULL
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
struct
sctphdr
*
sh
;
struct
sctphdr
*
sh
;
union
sctp_addr
src
;
union
sctp_addr
src
;
union
sctp_addr
dest
;
union
sctp_addr
dest
;
...
@@ -250,13 +250,13 @@ int sctp_rcv(struct sk_buff *skb)
...
@@ -250,13 +250,13 @@ int sctp_rcv(struct sk_buff *skb)
*/
*/
int
sctp_backlog_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
int
sctp_backlog_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
{
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
struct
sctp_inq
*
inqueue
;
struct
sctp_inq
*
inqueue
;
/* One day chunk will live inside the skb, but for
/* One day chunk will live inside the skb, but for
* now this works.
* now this works.
*/
*/
chunk
=
(
s
ctp_chunk_t
*
)
skb
;
chunk
=
(
s
truct
sctp_chunk
*
)
skb
;
inqueue
=
&
chunk
->
rcvr
->
inqueue
;
inqueue
=
&
chunk
->
rcvr
->
inqueue
;
sctp_inq_push
(
inqueue
,
chunk
);
sctp_inq_push
(
inqueue
,
chunk
);
...
...
net/sctp/inqueue.c
View file @
6cf4b403
...
@@ -75,17 +75,17 @@ struct sctp_inq *sctp_inq_new(void)
...
@@ -75,17 +75,17 @@ struct sctp_inq *sctp_inq_new(void)
/* Release the memory associated with an SCTP inqueue. */
/* Release the memory associated with an SCTP inqueue. */
void
sctp_inq_free
(
struct
sctp_inq
*
queue
)
void
sctp_inq_free
(
struct
sctp_inq
*
queue
)
{
{
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
/* Empty the queue. */
/* Empty the queue. */
while
((
chunk
=
(
s
ctp_chunk_t
*
)
skb_dequeue
(
&
queue
->
in
)))
while
((
chunk
=
(
s
truct
sctp_chunk
*
)
skb_dequeue
(
&
queue
->
in
)))
sctp_
free_chunk
(
chunk
);
sctp_
chunk_free
(
chunk
);
/* If there is a packet which is currently being worked on,
/* If there is a packet which is currently being worked on,
* free it as well.
* free it as well.
*/
*/
if
(
queue
->
in_progress
)
if
(
queue
->
in_progress
)
sctp_
free_chunk
(
queue
->
in_progress
);
sctp_
chunk_free
(
queue
->
in_progress
);
if
(
queue
->
malloced
)
{
if
(
queue
->
malloced
)
{
/* Dump the master memory segment. */
/* Dump the master memory segment. */
...
@@ -96,7 +96,7 @@ void sctp_inq_free(struct sctp_inq *queue)
...
@@ -96,7 +96,7 @@ void sctp_inq_free(struct sctp_inq *queue)
/* Put a new packet in an SCTP inqueue.
/* Put a new packet in an SCTP inqueue.
* We assume that packet->sctp_hdr is set and in host byte order.
* We assume that packet->sctp_hdr is set and in host byte order.
*/
*/
void
sctp_inq_push
(
struct
sctp_inq
*
q
,
s
ctp_chunk_t
*
packet
)
void
sctp_inq_push
(
struct
sctp_inq
*
q
,
s
truct
sctp_chunk
*
packet
)
{
{
/* Directly call the packet handling routine. */
/* Directly call the packet handling routine. */
...
@@ -114,9 +114,9 @@ void sctp_inq_push(struct sctp_inq *q, sctp_chunk_t *packet)
...
@@ -114,9 +114,9 @@ void sctp_inq_push(struct sctp_inq *q, sctp_chunk_t *packet)
* WARNING: If you need to put the chunk on another queue, you need to
* WARNING: If you need to put the chunk on another queue, you need to
* make a shallow copy (clone) of it.
* make a shallow copy (clone) of it.
*/
*/
s
ctp_chunk_t
*
sctp_inq_pop
(
struct
sctp_inq
*
queue
)
s
truct
sctp_chunk
*
sctp_inq_pop
(
struct
sctp_inq
*
queue
)
{
{
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
sctp_chunkhdr_t
*
ch
=
NULL
;
sctp_chunkhdr_t
*
ch
=
NULL
;
/* The assumption is that we are safe to process the chunks
/* The assumption is that we are safe to process the chunks
...
@@ -130,7 +130,7 @@ sctp_chunk_t *sctp_inq_pop(struct sctp_inq *queue)
...
@@ -130,7 +130,7 @@ sctp_chunk_t *sctp_inq_pop(struct sctp_inq *queue)
if
(
chunk
->
singleton
||
if
(
chunk
->
singleton
||
chunk
->
end_of_packet
||
chunk
->
end_of_packet
||
chunk
->
pdiscard
)
{
chunk
->
pdiscard
)
{
sctp_
free_chunk
(
chunk
);
sctp_
chunk_free
(
chunk
);
chunk
=
queue
->
in_progress
=
NULL
;
chunk
=
queue
->
in_progress
=
NULL
;
}
else
{
}
else
{
/* Nothing to do. Next chunk in the packet, please. */
/* Nothing to do. Next chunk in the packet, please. */
...
@@ -149,7 +149,7 @@ sctp_chunk_t *sctp_inq_pop(struct sctp_inq *queue)
...
@@ -149,7 +149,7 @@ sctp_chunk_t *sctp_inq_pop(struct sctp_inq *queue)
return
NULL
;
return
NULL
;
chunk
=
queue
->
in_progress
=
chunk
=
queue
->
in_progress
=
(
s
ctp_chunk_t
*
)
skb_dequeue
(
&
queue
->
in
);
(
s
truct
sctp_chunk
*
)
skb_dequeue
(
&
queue
->
in
);
/* This is the first chunk in the packet. */
/* This is the first chunk in the packet. */
chunk
->
singleton
=
1
;
chunk
->
singleton
=
1
;
...
...
net/sctp/ipv6.c
View file @
6cf4b403
...
@@ -246,7 +246,7 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
...
@@ -246,7 +246,7 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
void
sctp_v6_get_saddr
(
struct
sctp_association
*
asoc
,
struct
dst_entry
*
dst
,
void
sctp_v6_get_saddr
(
struct
sctp_association
*
asoc
,
struct
dst_entry
*
dst
,
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
{
{
s
ctp_bind_addr_t
*
bp
;
s
truct
sctp_bind_addr
*
bp
;
rwlock_t
*
addr_lock
;
rwlock_t
*
addr_lock
;
struct
sockaddr_storage_list
*
laddr
;
struct
sockaddr_storage_list
*
laddr
;
struct
list_head
*
pos
;
struct
list_head
*
pos
;
...
...
net/sctp/objcnt.c
View file @
6cf4b403
...
@@ -55,6 +55,7 @@ SCTP_DBG_OBJCNT(bind_addr);
...
@@ -55,6 +55,7 @@ SCTP_DBG_OBJCNT(bind_addr);
SCTP_DBG_OBJCNT
(
chunk
);
SCTP_DBG_OBJCNT
(
chunk
);
SCTP_DBG_OBJCNT
(
addr
);
SCTP_DBG_OBJCNT
(
addr
);
SCTP_DBG_OBJCNT
(
ssnmap
);
SCTP_DBG_OBJCNT
(
ssnmap
);
SCTP_DBG_OBJCNT
(
datamsg
);
/* An array to make it easy to pretty print the debug information
/* An array to make it easy to pretty print the debug information
* to the proc fs.
* to the proc fs.
...
@@ -68,6 +69,7 @@ sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
...
@@ -68,6 +69,7 @@ sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
SCTP_DBG_OBJCNT_ENTRY
(
bind_addr
),
SCTP_DBG_OBJCNT_ENTRY
(
bind_addr
),
SCTP_DBG_OBJCNT_ENTRY
(
addr
),
SCTP_DBG_OBJCNT_ENTRY
(
addr
),
SCTP_DBG_OBJCNT_ENTRY
(
ssnmap
),
SCTP_DBG_OBJCNT_ENTRY
(
ssnmap
),
SCTP_DBG_OBJCNT_ENTRY
(
datamsg
),
};
};
/* Callback from procfs to read out objcount information.
/* Callback from procfs to read out objcount information.
...
...
net/sctp/output.c
View file @
6cf4b403
...
@@ -114,7 +114,7 @@ void sctp_packet_free(struct sctp_packet *packet)
...
@@ -114,7 +114,7 @@ void sctp_packet_free(struct sctp_packet *packet)
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
;
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
)))
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
)))
sctp_
free_chunk
(
chunk
);
sctp_
chunk_free
(
chunk
);
if
(
packet
->
malloced
)
if
(
packet
->
malloced
)
kfree
(
packet
);
kfree
(
packet
);
...
@@ -327,7 +327,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -327,7 +327,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
sh
->
vtag
=
htonl
(
packet
->
vtag
);
sh
->
vtag
=
htonl
(
packet
->
vtag
);
sh
->
checksum
=
0
;
sh
->
checksum
=
0
;
/* 2) Calculate the Adler-32 checksum of the whole packet,
/* 2) Calculate the Adler-32 checksum of the whole packet,
* including the SCTP common header and all the
* including the SCTP common header and all the
* chunks.
* chunks.
...
@@ -358,9 +357,10 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -358,9 +357,10 @@ int sctp_packet_transmit(struct sctp_packet *packet)
*/
*/
SCTP_DEBUG_PRINTK
(
"***sctp_transmit_packet***
\n
"
);
SCTP_DEBUG_PRINTK
(
"***sctp_transmit_packet***
\n
"
);
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
)))
{
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
)))
{
chunk
->
num_times_sent
++
;
chunk
->
sent_at
=
jiffies
;
if
(
sctp_chunk_is_data
(
chunk
))
{
if
(
sctp_chunk_is_data
(
chunk
))
{
if
(
!
chunk
->
has_tsn
)
{
sctp_chunk_assign_tsn
(
chunk
);
sctp_chunk_assign_tsn
(
chunk
);
/* 6.3.1 C4) When data is in flight and when allowed
/* 6.3.1 C4) When data is in flight and when allowed
...
@@ -369,13 +369,19 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -369,13 +369,19 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* SHOULD be made no more than once per round-trip
* SHOULD be made no more than once per round-trip
* for a given destination transport address.
* for a given destination transport address.
*/
*/
if
((
1
==
chunk
->
num_times_sent
)
&&
(
!
tp
->
rto_pending
)
)
{
if
(
!
tp
->
rto_pending
)
{
chunk
->
rtt_in_progress
=
1
;
chunk
->
rtt_in_progress
=
1
;
tp
->
rto_pending
=
1
;
tp
->
rto_pending
=
1
;
}
}
sctp_datamsg_track
(
chunk
);
}
else
chunk
->
resent
=
1
;
chunk
->
sent_at
=
jiffies
;
has_data
=
1
;
has_data
=
1
;
}
}
padding
=
WORD_ROUND
(
chunk
->
skb
->
len
)
-
chunk
->
skb
->
len
;
padding
=
WORD_ROUND
(
chunk
->
skb
->
len
)
-
chunk
->
skb
->
len
;
if
(
padding
)
if
(
padding
)
memset
(
skb_put
(
chunk
->
skb
,
padding
),
0
,
padding
);
memset
(
skb_put
(
chunk
->
skb
,
padding
),
0
,
padding
);
...
@@ -384,8 +390,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -384,8 +390,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
chunk
->
skb
->
data
,
chunk
->
skb
->
data
,
chunk
->
skb
->
len
,
crc32
);
chunk
->
skb
->
len
,
crc32
);
SCTP_DEBUG_PRINTK
(
"%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d, "
SCTP_DEBUG_PRINTK
(
"%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d
\n
"
,
"%s %d
\n
"
,
"*** Chunk"
,
chunk
,
"*** Chunk"
,
chunk
,
sctp_cname
(
SCTP_ST_CHUNK
(
sctp_cname
(
SCTP_ST_CHUNK
(
chunk
->
chunk_hdr
->
type
)),
chunk
->
chunk_hdr
->
type
)),
...
@@ -394,7 +399,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -394,7 +399,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
)
:
0
,
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
)
:
0
,
"length"
,
ntohs
(
chunk
->
chunk_hdr
->
length
),
"length"
,
ntohs
(
chunk
->
chunk_hdr
->
length
),
"chunk->skb->len"
,
chunk
->
skb
->
len
,
"chunk->skb->len"
,
chunk
->
skb
->
len
,
"num_times_sent"
,
chunk
->
num_times_sent
,
"rtt_in_progress"
,
chunk
->
rtt_in_progress
);
"rtt_in_progress"
,
chunk
->
rtt_in_progress
);
/*
/*
...
@@ -403,7 +407,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -403,7 +407,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* acknowledged or have failed.
* acknowledged or have failed.
*/
*/
if
(
!
sctp_chunk_is_data
(
chunk
))
if
(
!
sctp_chunk_is_data
(
chunk
))
sctp_free_chunk
(
chunk
);
sctp_chunk_free
(
chunk
);
}
}
/* Perform final transformation on checksum. */
/* Perform final transformation on checksum. */
...
...
net/sctp/outqueue.c
View file @
6cf4b403
...
@@ -143,14 +143,14 @@ void sctp_outq_teardown(struct sctp_outq *q)
...
@@ -143,14 +143,14 @@ void sctp_outq_teardown(struct sctp_outq *q)
{
{
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
struct
list_head
*
lchunk
,
*
pos
,
*
temp
;
struct
list_head
*
lchunk
,
*
pos
,
*
temp
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
struct
sctp_ulpevent
*
ev
;
struct
sctp_ulpevent
*
ev
;
/* Throw away unacknowledged chunks. */
/* Throw away unacknowledged chunks. */
list_for_each
(
pos
,
&
q
->
asoc
->
peer
.
transport_addr_list
)
{
list_for_each
(
pos
,
&
q
->
asoc
->
peer
.
transport_addr_list
)
{
transport
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
transport
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
while
((
lchunk
=
sctp_list_dequeue
(
&
transport
->
transmitted
)))
{
while
((
lchunk
=
sctp_list_dequeue
(
&
transport
->
transmitted
)))
{
chunk
=
list_entry
(
lchunk
,
s
ctp_chunk_t
,
chunk
=
list_entry
(
lchunk
,
s
truct
sctp_chunk
,
transmitted_list
);
transmitted_list
);
/* Generate a SEND FAILED event. */
/* Generate a SEND FAILED event. */
...
@@ -160,22 +160,24 @@ void sctp_outq_teardown(struct sctp_outq *q)
...
@@ -160,22 +160,24 @@ void sctp_outq_teardown(struct sctp_outq *q)
if
(
ev
)
if
(
ev
)
sctp_ulpq_tail_event
(
&
q
->
asoc
->
ulpq
,
ev
);
sctp_ulpq_tail_event
(
&
q
->
asoc
->
ulpq
,
ev
);
sctp_
free_chunk
(
chunk
);
sctp_
chunk_free
(
chunk
);
}
}
}
}
/* Throw away chunks that have been gap ACKed. */
/* Throw away chunks that have been gap ACKed. */
list_for_each_safe
(
lchunk
,
temp
,
&
q
->
sacked
)
{
list_for_each_safe
(
lchunk
,
temp
,
&
q
->
sacked
)
{
list_del
(
lchunk
);
list_del
(
lchunk
);
chunk
=
list_entry
(
lchunk
,
sctp_chunk_t
,
transmitted_list
);
chunk
=
list_entry
(
lchunk
,
struct
sctp_chunk
,
sctp_free_chunk
(
chunk
);
transmitted_list
);
sctp_chunk_free
(
chunk
);
}
}
/* Throw away any chunks in the retransmit queue. */
/* Throw away any chunks in the retransmit queue. */
list_for_each_safe
(
lchunk
,
temp
,
&
q
->
retransmit
)
{
list_for_each_safe
(
lchunk
,
temp
,
&
q
->
retransmit
)
{
list_del
(
lchunk
);
list_del
(
lchunk
);
chunk
=
list_entry
(
lchunk
,
sctp_chunk_t
,
transmitted_list
);
chunk
=
list_entry
(
lchunk
,
struct
sctp_chunk
,
sctp_free_chunk
(
chunk
);
transmitted_list
);
sctp_chunk_free
(
chunk
);
}
}
/* Throw away any leftover data chunks. */
/* Throw away any leftover data chunks. */
...
@@ -188,14 +190,14 @@ void sctp_outq_teardown(struct sctp_outq *q)
...
@@ -188,14 +190,14 @@ void sctp_outq_teardown(struct sctp_outq *q)
if
(
ev
)
if
(
ev
)
sctp_ulpq_tail_event
(
&
q
->
asoc
->
ulpq
,
ev
);
sctp_ulpq_tail_event
(
&
q
->
asoc
->
ulpq
,
ev
);
sctp_
free_chunk
(
chunk
);
sctp_
chunk_free
(
chunk
);
}
}
q
->
error
=
0
;
q
->
error
=
0
;
/* Throw away any leftover control chunks. */
/* Throw away any leftover control chunks. */
while
((
chunk
=
(
s
ctp_chunk_t
*
)
skb_dequeue
(
&
q
->
control
)))
while
((
chunk
=
(
s
truct
sctp_chunk
*
)
skb_dequeue
(
&
q
->
control
)))
sctp_
free_chunk
(
chunk
);
sctp_
chunk_free
(
chunk
);
}
}
/* Free the outqueue structure and any related pending chunks. */
/* Free the outqueue structure and any related pending chunks. */
...
@@ -210,7 +212,7 @@ void sctp_outq_free(struct sctp_outq *q)
...
@@ -210,7 +212,7 @@ void sctp_outq_free(struct sctp_outq *q)
}
}
/* Put a new chunk in an sctp_outq. */
/* Put a new chunk in an sctp_outq. */
int
sctp_outq_tail
(
struct
sctp_outq
*
q
,
s
ctp_chunk_t
*
chunk
)
int
sctp_outq_tail
(
struct
sctp_outq
*
q
,
s
truct
sctp_chunk
*
chunk
)
{
{
int
error
=
0
;
int
error
=
0
;
...
@@ -276,15 +278,16 @@ int sctp_outq_tail(struct sctp_outq *q, sctp_chunk_t *chunk)
...
@@ -276,15 +278,16 @@ int sctp_outq_tail(struct sctp_outq *q, sctp_chunk_t *chunk)
void
sctp_retransmit_insert
(
struct
list_head
*
tlchunk
,
struct
sctp_outq
*
q
)
void
sctp_retransmit_insert
(
struct
list_head
*
tlchunk
,
struct
sctp_outq
*
q
)
{
{
struct
list_head
*
rlchunk
;
struct
list_head
*
rlchunk
;
s
ctp_chunk_t
*
tchunk
,
*
rchunk
;
s
truct
sctp_chunk
*
tchunk
,
*
rchunk
;
__u32
ttsn
,
rtsn
;
__u32
ttsn
,
rtsn
;
int
done
=
0
;
int
done
=
0
;
tchunk
=
list_entry
(
tlchunk
,
s
ctp_chunk_t
,
transmitted_list
);
tchunk
=
list_entry
(
tlchunk
,
s
truct
sctp_chunk
,
transmitted_list
);
ttsn
=
ntohl
(
tchunk
->
subh
.
data_hdr
->
tsn
);
ttsn
=
ntohl
(
tchunk
->
subh
.
data_hdr
->
tsn
);
list_for_each
(
rlchunk
,
&
q
->
retransmit
)
{
list_for_each
(
rlchunk
,
&
q
->
retransmit
)
{
rchunk
=
list_entry
(
rlchunk
,
sctp_chunk_t
,
transmitted_list
);
rchunk
=
list_entry
(
rlchunk
,
struct
sctp_chunk
,
transmitted_list
);
rtsn
=
ntohl
(
rchunk
->
subh
.
data_hdr
->
tsn
);
rtsn
=
ntohl
(
rchunk
->
subh
.
data_hdr
->
tsn
);
if
(
TSN_lt
(
ttsn
,
rtsn
))
{
if
(
TSN_lt
(
ttsn
,
rtsn
))
{
list_add
(
tlchunk
,
rlchunk
->
prev
);
list_add
(
tlchunk
,
rlchunk
->
prev
);
...
@@ -303,11 +306,12 @@ void sctp_retransmit_mark(struct sctp_outq *q,
...
@@ -303,11 +306,12 @@ void sctp_retransmit_mark(struct sctp_outq *q,
__u8
fast_retransmit
)
__u8
fast_retransmit
)
{
{
struct
list_head
*
lchunk
,
*
ltemp
;
struct
list_head
*
lchunk
,
*
ltemp
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
/* Walk through the specified transmitted queue. */
/* Walk through the specified transmitted queue. */
list_for_each_safe
(
lchunk
,
ltemp
,
&
transport
->
transmitted
)
{
list_for_each_safe
(
lchunk
,
ltemp
,
&
transport
->
transmitted
)
{
chunk
=
list_entry
(
lchunk
,
sctp_chunk_t
,
transmitted_list
);
chunk
=
list_entry
(
lchunk
,
struct
sctp_chunk
,
transmitted_list
);
/* If we are doing retransmission due to a fast retransmit,
/* If we are doing retransmission due to a fast retransmit,
* only the chunk's that are marked for fast retransmit
* only the chunk's that are marked for fast retransmit
...
@@ -416,7 +420,7 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
...
@@ -416,7 +420,7 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
struct
list_head
*
lchunk
;
struct
list_head
*
lchunk
;
struct
sctp_transport
*
transport
=
pkt
->
transport
;
struct
sctp_transport
*
transport
=
pkt
->
transport
;
sctp_xmit_t
status
;
sctp_xmit_t
status
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
struct
sctp_association
*
asoc
;
struct
sctp_association
*
asoc
;
int
error
=
0
;
int
error
=
0
;
...
@@ -442,7 +446,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
...
@@ -442,7 +446,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
lchunk
=
sctp_list_dequeue
(
lqueue
);
lchunk
=
sctp_list_dequeue
(
lqueue
);
while
(
lchunk
)
{
while
(
lchunk
)
{
chunk
=
list_entry
(
lchunk
,
sctp_chunk_t
,
transmitted_list
);
chunk
=
list_entry
(
lchunk
,
struct
sctp_chunk
,
transmitted_list
);
/* Make sure that Gap Acked TSNs are not retransmitted. A
/* Make sure that Gap Acked TSNs are not retransmitted. A
* simple approach is just to move such TSNs out of the
* simple approach is just to move such TSNs out of the
...
@@ -582,7 +587,7 @@ void sctp_xmit_frag(struct sctp_outq *q, struct sctp_chunk *pos,
...
@@ -582,7 +587,7 @@ void sctp_xmit_frag(struct sctp_outq *q, struct sctp_chunk *pos,
* of all the other fragments in the 'frag_list' field.
* of all the other fragments in the 'frag_list' field.
*/
*/
void
sctp_xmit_fragmented_chunks
(
struct
sctp_outq
*
q
,
struct
sctp_packet
*
pkt
,
void
sctp_xmit_fragmented_chunks
(
struct
sctp_outq
*
q
,
struct
sctp_packet
*
pkt
,
s
ctp_chunk_t
*
frag
)
s
truct
sctp_chunk
*
frag
)
{
{
struct
sctp_association
*
asoc
=
frag
->
asoc
;
struct
sctp_association
*
asoc
=
frag
->
asoc
;
struct
list_head
*
lfrag
,
*
frag_list
;
struct
list_head
*
lfrag
,
*
frag_list
;
...
@@ -606,7 +611,7 @@ void sctp_xmit_fragmented_chunks(struct sctp_outq *q, struct sctp_packet *pkt,
...
@@ -606,7 +611,7 @@ void sctp_xmit_fragmented_chunks(struct sctp_outq *q, struct sctp_packet *pkt,
/* Transmit the rest of fragments. */
/* Transmit the rest of fragments. */
frag_list
=
&
frag
->
frag_list
;
frag_list
=
&
frag
->
frag_list
;
list_for_each
(
lfrag
,
frag_list
)
{
list_for_each
(
lfrag
,
frag_list
)
{
frag
=
list_entry
(
lfrag
,
s
ctp_chunk_t
,
frag_list
);
frag
=
list_entry
(
lfrag
,
s
truct
sctp_chunk
,
frag_list
);
sctp_xmit_frag
(
q
,
pos
,
pkt
,
frag
,
tsn
++
);
sctp_xmit_frag
(
q
,
pos
,
pkt
,
frag
,
tsn
++
);
}
}
}
}
...
@@ -615,7 +620,7 @@ void sctp_xmit_fragmented_chunks(struct sctp_outq *q, struct sctp_packet *pkt,
...
@@ -615,7 +620,7 @@ void sctp_xmit_fragmented_chunks(struct sctp_outq *q, struct sctp_packet *pkt,
* fragments. It returns the first fragment with the frag_list field holding
* fragments. It returns the first fragment with the frag_list field holding
* the remaining fragments.
* the remaining fragments.
*/
*/
s
ctp_chunk_t
*
sctp_fragment_chunk
(
sctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
sctp_fragment_chunk
(
struct
sctp_chunk
*
chunk
,
size_t
max_frag_data_len
)
size_t
max_frag_data_len
)
{
{
struct
sctp_association
*
asoc
=
chunk
->
asoc
;
struct
sctp_association
*
asoc
=
chunk
->
asoc
;
...
@@ -623,7 +628,7 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
...
@@ -623,7 +628,7 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
struct
sctp_sndrcvinfo
*
sinfo
=
&
chunk
->
sinfo
;
struct
sctp_sndrcvinfo
*
sinfo
=
&
chunk
->
sinfo
;
__u16
chunk_data_len
=
sctp_data_size
(
chunk
);
__u16
chunk_data_len
=
sctp_data_size
(
chunk
);
__u16
ssn
=
ntohs
(
chunk
->
subh
.
data_hdr
->
ssn
);
__u16
ssn
=
ntohs
(
chunk
->
subh
.
data_hdr
->
ssn
);
s
ctp_chunk_t
*
first_frag
,
*
frag
;
s
truct
sctp_chunk
*
first_frag
,
*
frag
;
struct
list_head
*
frag_list
;
struct
list_head
*
frag_list
;
int
nfrags
;
int
nfrags
;
__u8
old_flags
,
flags
;
__u8
old_flags
,
flags
;
...
@@ -648,6 +653,7 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
...
@@ -648,6 +653,7 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
if
(
!
first_frag
)
if
(
!
first_frag
)
goto
err
;
goto
err
;
sctp_datamsg_assign
(
chunk
->
msg
,
first_frag
);
first_frag
->
has_ssn
=
1
;
first_frag
->
has_ssn
=
1
;
/* All the fragments are added to the frag_list of the first chunk. */
/* All the fragments are added to the frag_list of the first chunk. */
frag_list
=
&
first_frag
->
frag_list
;
frag_list
=
&
first_frag
->
frag_list
;
...
@@ -662,6 +668,7 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
...
@@ -662,6 +668,7 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
ssn
);
ssn
);
if
(
!
frag
)
if
(
!
frag
)
goto
err
;
goto
err
;
sctp_datamsg_assign
(
chunk
->
msg
,
frag
);
frag
->
has_ssn
=
1
;
frag
->
has_ssn
=
1
;
/* Add the middle fragment to the first fragment's
/* Add the middle fragment to the first fragment's
* frag_list.
* frag_list.
...
@@ -682,13 +689,14 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
...
@@ -682,13 +689,14 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
flags
,
ssn
);
flags
,
ssn
);
if
(
!
frag
)
if
(
!
frag
)
goto
err
;
goto
err
;
sctp_datamsg_assign
(
chunk
->
msg
,
frag
);
frag
->
has_ssn
=
1
;
frag
->
has_ssn
=
1
;
/* Add the last fragment to the first fragment's frag_list. */
/* Add the last fragment to the first fragment's frag_list. */
list_add_tail
(
&
frag
->
frag_list
,
frag_list
);
list_add_tail
(
&
frag
->
frag_list
,
frag_list
);
/* Free the original chunk. */
/* Free the original chunk. */
sctp_
free_chunk
(
chunk
);
sctp_
chunk_free
(
chunk
);
return
first_frag
;
return
first_frag
;
...
@@ -700,12 +708,11 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
...
@@ -700,12 +708,11 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
/* Free all the fragments off the first one. */
/* Free all the fragments off the first one. */
flist
=
&
first_frag
->
frag_list
;
flist
=
&
first_frag
->
frag_list
;
while
(
NULL
!=
(
lfrag
=
sctp_list_dequeue
(
flist
)))
{
while
(
NULL
!=
(
lfrag
=
sctp_list_dequeue
(
flist
)))
{
frag
=
list_entry
(
lfrag
,
s
ctp_chunk_t
,
frag_list
);
frag
=
list_entry
(
lfrag
,
s
truct
sctp_chunk
,
frag_list
);
sctp_
free_chunk
(
frag
);
sctp_
chunk_free
(
frag
);
}
}
/* Free the first fragment. */
/* Free the first fragment. */
sctp_
free_chunk
(
first_frag
);
sctp_
chunk_free
(
first_frag
);
}
}
return
NULL
;
return
NULL
;
...
@@ -735,7 +742,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -735,7 +742,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
struct
sk_buff_head
*
queue
;
struct
sk_buff_head
*
queue
;
struct
sctp_transport
*
transport
=
NULL
;
struct
sctp_transport
*
transport
=
NULL
;
struct
sctp_transport
*
new_transport
;
struct
sctp_transport
*
new_transport
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
sctp_xmit_t
status
;
sctp_xmit_t
status
;
int
error
=
0
;
int
error
=
0
;
int
start_timer
=
0
;
int
start_timer
=
0
;
...
@@ -762,7 +769,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -762,7 +769,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
}
}
queue
=
&
q
->
control
;
queue
=
&
q
->
control
;
while
((
chunk
=
(
s
ctp_chunk_t
*
)
skb_dequeue
(
queue
)))
{
while
((
chunk
=
(
s
truct
sctp_chunk
*
)
skb_dequeue
(
queue
)))
{
/* Pick the right transport to use. */
/* Pick the right transport to use. */
new_transport
=
chunk
->
transport
;
new_transport
=
chunk
->
transport
;
...
@@ -912,7 +919,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -912,7 +919,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
sctp_ulpq_tail_event
(
&
asoc
->
ulpq
,
ev
);
sctp_ulpq_tail_event
(
&
asoc
->
ulpq
,
ev
);
/* Free the chunk. */
/* Free the chunk. */
sctp_
free_chunk
(
chunk
);
sctp_
chunk_free
(
chunk
);
continue
;
continue
;
}
}
...
@@ -980,7 +987,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -980,7 +987,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
break
;
break
;
case
SCTP_XMIT_MUST_FRAG
:
{
case
SCTP_XMIT_MUST_FRAG
:
{
s
ctp_chunk_t
*
frag
;
s
truct
sctp_chunk
*
frag
;
frag
=
sctp_fragment_chunk
(
chunk
,
frag
=
sctp_fragment_chunk
(
chunk
,
packet
->
transport
->
asoc
->
frag_point
);
packet
->
transport
->
asoc
->
frag_point
);
...
@@ -989,7 +996,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -989,7 +996,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
* memory condition. Free the original
* memory condition. Free the original
* chunk and return ENOMEM.
* chunk and return ENOMEM.
*/
*/
sctp_
free_chunk
(
chunk
);
sctp_
chunk_free
(
chunk
);
error
=
-
ENOMEM
;
error
=
-
ENOMEM
;
return
error
;
return
error
;
}
}
...
@@ -1101,7 +1108,7 @@ static __u32 sctp_highest_new_tsn(sctp_sackhdr_t *sack,
...
@@ -1101,7 +1108,7 @@ static __u32 sctp_highest_new_tsn(sctp_sackhdr_t *sack,
{
{
struct
list_head
*
ltransport
,
*
lchunk
;
struct
list_head
*
ltransport
,
*
lchunk
;
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
__u32
highest_new_tsn
,
tsn
;
__u32
highest_new_tsn
,
tsn
;
struct
list_head
*
transport_list
=
&
asoc
->
peer
.
transport_addr_list
;
struct
list_head
*
transport_list
=
&
asoc
->
peer
.
transport_addr_list
;
...
@@ -1111,7 +1118,7 @@ static __u32 sctp_highest_new_tsn(sctp_sackhdr_t *sack,
...
@@ -1111,7 +1118,7 @@ static __u32 sctp_highest_new_tsn(sctp_sackhdr_t *sack,
transport
=
list_entry
(
ltransport
,
struct
sctp_transport
,
transport
=
list_entry
(
ltransport
,
struct
sctp_transport
,
transports
);
transports
);
list_for_each
(
lchunk
,
&
transport
->
transmitted
)
{
list_for_each
(
lchunk
,
&
transport
->
transmitted
)
{
chunk
=
list_entry
(
lchunk
,
s
ctp_chunk_t
,
chunk
=
list_entry
(
lchunk
,
s
truct
sctp_chunk
,
transmitted_list
);
transmitted_list
);
tsn
=
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
);
tsn
=
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
);
...
@@ -1134,7 +1141,7 @@ int sctp_outq_sack(struct sctp_outq *q, sctp_sackhdr_t *sack)
...
@@ -1134,7 +1141,7 @@ int sctp_outq_sack(struct sctp_outq *q, sctp_sackhdr_t *sack)
{
{
struct
sctp_association
*
asoc
=
q
->
asoc
;
struct
sctp_association
*
asoc
=
q
->
asoc
;
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
s
ctp_chunk_t
*
tchunk
;
s
truct
sctp_chunk
*
tchunk
;
struct
list_head
*
lchunk
,
*
transport_list
,
*
pos
;
struct
list_head
*
lchunk
,
*
transport_list
,
*
pos
;
sctp_sack_variable_t
*
frags
=
sack
->
variable
;
sctp_sack_variable_t
*
frags
=
sack
->
variable
;
__u32
sack_ctsn
,
ctsn
,
tsn
;
__u32
sack_ctsn
,
ctsn
,
tsn
;
...
@@ -1191,11 +1198,12 @@ int sctp_outq_sack(struct sctp_outq *q, sctp_sackhdr_t *sack)
...
@@ -1191,11 +1198,12 @@ int sctp_outq_sack(struct sctp_outq *q, sctp_sackhdr_t *sack)
/* Throw away stuff rotting on the sack queue. */
/* Throw away stuff rotting on the sack queue. */
list_for_each
(
lchunk
,
&
q
->
sacked
)
{
list_for_each
(
lchunk
,
&
q
->
sacked
)
{
tchunk
=
list_entry
(
lchunk
,
sctp_chunk_t
,
transmitted_list
);
tchunk
=
list_entry
(
lchunk
,
struct
sctp_chunk
,
transmitted_list
);
tsn
=
ntohl
(
tchunk
->
subh
.
data_hdr
->
tsn
);
tsn
=
ntohl
(
tchunk
->
subh
.
data_hdr
->
tsn
);
if
(
TSN_lte
(
tsn
,
ctsn
))
{
if
(
TSN_lte
(
tsn
,
ctsn
))
{
lchunk
=
lchunk
->
prev
;
lchunk
=
lchunk
->
prev
;
sctp_
free_chunk
(
tchunk
);
sctp_
chunk_free
(
tchunk
);
}
}
}
}
...
@@ -1264,7 +1272,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
...
@@ -1264,7 +1272,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
__u32
highest_new_tsn_in_sack
)
__u32
highest_new_tsn_in_sack
)
{
{
struct
list_head
*
lchunk
;
struct
list_head
*
lchunk
;
s
ctp_chunk_t
*
tchunk
;
s
truct
sctp_chunk
*
tchunk
;
struct
list_head
tlist
;
struct
list_head
tlist
;
__u32
tsn
;
__u32
tsn
;
__u32
sack_ctsn
;
__u32
sack_ctsn
;
...
@@ -1294,7 +1302,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
...
@@ -1294,7 +1302,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
/* The while loop will skip empty transmitted queues. */
/* The while loop will skip empty transmitted queues. */
while
(
NULL
!=
(
lchunk
=
sctp_list_dequeue
(
transmitted_queue
)))
{
while
(
NULL
!=
(
lchunk
=
sctp_list_dequeue
(
transmitted_queue
)))
{
tchunk
=
list_entry
(
lchunk
,
sctp_chunk_t
,
transmitted_list
);
tchunk
=
list_entry
(
lchunk
,
struct
sctp_chunk
,
transmitted_list
);
tsn
=
ntohl
(
tchunk
->
subh
.
data_hdr
->
tsn
);
tsn
=
ntohl
(
tchunk
->
subh
.
data_hdr
->
tsn
);
if
(
sctp_acked
(
sack
,
tsn
))
{
if
(
sctp_acked
(
sack
,
tsn
))
{
...
@@ -1315,9 +1324,9 @@ static void sctp_check_transmitted(struct sctp_outq *q,
...
@@ -1315,9 +1324,9 @@ static void sctp_check_transmitted(struct sctp_outq *q,
* first instance of the packet or a later
* first instance of the packet or a later
* instance).
* instance).
*/
*/
if
(
(
!
tchunk
->
tsn_gap_acked
)
&&
if
(
!
tchunk
->
tsn_gap_acked
&&
(
1
==
tchunk
->
num_times_sent
)
&&
!
tchunk
->
resent
&&
(
tchunk
->
rtt_in_progress
)
)
{
tchunk
->
rtt_in_progress
)
{
rtt
=
jiffies
-
tchunk
->
sent_at
;
rtt
=
jiffies
-
tchunk
->
sent_at
;
sctp_transport_update_rto
(
transport
,
sctp_transport_update_rto
(
transport
,
rtt
);
rtt
);
...
@@ -1524,8 +1533,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
...
@@ -1524,8 +1533,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
* receiver's advertised window is zero, and there is
* receiver's advertised window is zero, and there is
* only one data chunk in flight to the receiver.
* only one data chunk in flight to the receiver.
*/
*/
if
(
(
0
==
q
->
asoc
->
peer
.
rwnd
)
&&
if
(
!
q
->
asoc
->
peer
.
rwnd
&&
(
!
list_empty
(
&
tlist
)
)
&&
!
list_empty
(
&
tlist
)
&&
(
sack_ctsn
+
2
==
q
->
asoc
->
next_tsn
))
{
(
sack_ctsn
+
2
==
q
->
asoc
->
next_tsn
))
{
SCTP_DEBUG_PRINTK
(
"%s: SACK received for zero "
SCTP_DEBUG_PRINTK
(
"%s: SACK received for zero "
"window probe: %u
\n
"
,
"window probe: %u
\n
"
,
...
@@ -1557,7 +1566,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
...
@@ -1557,7 +1566,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
* acked by the Cumulative TSN Ack.
* acked by the Cumulative TSN Ack.
*/
*/
while
(
NULL
!=
(
lchunk
=
sctp_list_dequeue
(
&
tlist
)))
{
while
(
NULL
!=
(
lchunk
=
sctp_list_dequeue
(
&
tlist
)))
{
tchunk
=
list_entry
(
lchunk
,
sctp_chunk_t
,
transmitted_list
);
tchunk
=
list_entry
(
lchunk
,
struct
sctp_chunk
,
transmitted_list
);
tsn
=
ntohl
(
tchunk
->
subh
.
data_hdr
->
tsn
);
tsn
=
ntohl
(
tchunk
->
subh
.
data_hdr
->
tsn
);
/* RFC 2960 7.2.4, sctpimpguide-05 2.8.2 M3) Examine all
/* RFC 2960 7.2.4, sctpimpguide-05 2.8.2 M3) Examine all
...
...
net/sctp/protocol.c
View file @
6cf4b403
...
@@ -393,7 +393,7 @@ struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
...
@@ -393,7 +393,7 @@ struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
{
{
struct
rtable
*
rt
;
struct
rtable
*
rt
;
struct
flowi
fl
;
struct
flowi
fl
;
s
ctp_bind_addr_t
*
bp
;
s
truct
sctp_bind_addr
*
bp
;
rwlock_t
*
addr_lock
;
rwlock_t
*
addr_lock
;
struct
sockaddr_storage_list
*
laddr
;
struct
sockaddr_storage_list
*
laddr
;
struct
list_head
*
pos
;
struct
list_head
*
pos
;
...
...
net/sctp/sm_make_chunk.c
View file @
6cf4b403
...
@@ -97,7 +97,7 @@ static const sctp_ecn_capable_param_t ecap_param = {
...
@@ -97,7 +97,7 @@ static const sctp_ecn_capable_param_t ecap_param = {
* provided chunk, as most cause codes will be embedded inside an
* provided chunk, as most cause codes will be embedded inside an
* abort chunk.
* abort chunk.
*/
*/
void
sctp_init_cause
(
s
ctp_chunk_t
*
chunk
,
__u16
cause_code
,
void
sctp_init_cause
(
s
truct
sctp_chunk
*
chunk
,
__u16
cause_code
,
const
void
*
payload
,
size_t
paylen
)
const
void
*
payload
,
size_t
paylen
)
{
{
sctp_errhdr_t
err
;
sctp_errhdr_t
err
;
...
@@ -158,14 +158,14 @@ void sctp_init_cause(sctp_chunk_t *chunk, __u16 cause_code,
...
@@ -158,14 +158,14 @@ void sctp_init_cause(sctp_chunk_t *chunk, __u16 cause_code,
* Host Name Address (Note 3) Optional 11
* Host Name Address (Note 3) Optional 11
* Supported Address Types (Note 4) Optional 12
* Supported Address Types (Note 4) Optional 12
*/
*/
s
ctp_chunk_t
*
sctp_make_init
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_init
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_bind_addr_t
*
bp
,
const
s
truct
sctp_bind_addr
*
bp
,
int
gfp
,
int
vparam_len
)
int
gfp
,
int
vparam_len
)
{
{
sctp_inithdr_t
init
;
sctp_inithdr_t
init
;
union
sctp_params
addrs
;
union
sctp_params
addrs
;
size_t
chunksize
;
size_t
chunksize
;
s
ctp_chunk_t
*
retval
=
NULL
;
s
truct
sctp_chunk
*
retval
=
NULL
;
int
num_types
,
addrs_len
=
0
;
int
num_types
,
addrs_len
=
0
;
struct
sctp_opt
*
sp
;
struct
sctp_opt
*
sp
;
sctp_supported_addrs_param_t
sat
;
sctp_supported_addrs_param_t
sat
;
...
@@ -235,12 +235,12 @@ sctp_chunk_t *sctp_make_init(const struct sctp_association *asoc,
...
@@ -235,12 +235,12 @@ sctp_chunk_t *sctp_make_init(const struct sctp_association *asoc,
return
retval
;
return
retval
;
}
}
s
ctp_chunk_t
*
sctp_make_init_ack
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_init_ack
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
,
const
s
truct
sctp_chunk
*
chunk
,
int
gfp
,
int
unkparam_len
)
int
gfp
,
int
unkparam_len
)
{
{
sctp_inithdr_t
initack
;
sctp_inithdr_t
initack
;
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
union
sctp_params
addrs
;
union
sctp_params
addrs
;
int
addrs_len
;
int
addrs_len
;
sctp_cookie_param_t
*
cookie
;
sctp_cookie_param_t
*
cookie
;
...
@@ -348,10 +348,10 @@ sctp_chunk_t *sctp_make_init_ack(const struct sctp_association *asoc,
...
@@ -348,10 +348,10 @@ sctp_chunk_t *sctp_make_init_ack(const struct sctp_association *asoc,
* An implementation SHOULD make the cookie as small as possible
* An implementation SHOULD make the cookie as small as possible
* to insure interoperability.
* to insure interoperability.
*/
*/
s
ctp_chunk_t
*
sctp_make_cookie_echo
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_cookie_echo
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
)
const
s
truct
sctp_chunk
*
chunk
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
void
*
cookie
;
void
*
cookie
;
int
cookie_len
;
int
cookie_len
;
...
@@ -399,10 +399,10 @@ sctp_chunk_t *sctp_make_cookie_echo(const struct sctp_association *asoc,
...
@@ -399,10 +399,10 @@ sctp_chunk_t *sctp_make_cookie_echo(const struct sctp_association *asoc,
*
*
* Set to zero on transmit and ignored on receipt.
* Set to zero on transmit and ignored on receipt.
*/
*/
s
ctp_chunk_t
*
sctp_make_cookie_ack
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_cookie_ack
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
)
const
s
truct
sctp_chunk
*
chunk
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_COOKIE_ACK
,
0
,
0
);
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_COOKIE_ACK
,
0
,
0
);
...
@@ -444,11 +444,11 @@ sctp_chunk_t *sctp_make_cookie_ack(const struct sctp_association *asoc,
...
@@ -444,11 +444,11 @@ sctp_chunk_t *sctp_make_cookie_ack(const struct sctp_association *asoc,
*
*
* Note: The CWR is considered a Control chunk.
* Note: The CWR is considered a Control chunk.
*/
*/
s
ctp_chunk_t
*
sctp_make_cwr
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_cwr
(
const
struct
sctp_association
*
asoc
,
const
__u32
lowest_tsn
,
const
__u32
lowest_tsn
,
const
s
ctp_chunk_t
*
chunk
)
const
s
truct
sctp_chunk
*
chunk
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
sctp_cwrhdr_t
cwr
;
sctp_cwrhdr_t
cwr
;
cwr
.
lowest_tsn
=
htonl
(
lowest_tsn
);
cwr
.
lowest_tsn
=
htonl
(
lowest_tsn
);
...
@@ -479,10 +479,10 @@ sctp_chunk_t *sctp_make_cwr(const struct sctp_association *asoc,
...
@@ -479,10 +479,10 @@ sctp_chunk_t *sctp_make_cwr(const struct sctp_association *asoc,
}
}
/* Make an ECNE chunk. This is a congestion experienced report. */
/* Make an ECNE chunk. This is a congestion experienced report. */
s
ctp_chunk_t
*
sctp_make_ecne
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_ecne
(
const
struct
sctp_association
*
asoc
,
const
__u32
lowest_tsn
)
const
__u32
lowest_tsn
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
sctp_ecnehdr_t
ecne
;
sctp_ecnehdr_t
ecne
;
ecne
.
lowest_tsn
=
htonl
(
lowest_tsn
);
ecne
.
lowest_tsn
=
htonl
(
lowest_tsn
);
...
@@ -500,25 +500,27 @@ sctp_chunk_t *sctp_make_ecne(const struct sctp_association *asoc,
...
@@ -500,25 +500,27 @@ sctp_chunk_t *sctp_make_ecne(const struct sctp_association *asoc,
/* Make a DATA chunk for the given association from the provided
/* Make a DATA chunk for the given association from the provided
* parameters. However, do not populate the data payload.
* parameters. However, do not populate the data payload.
*/
*/
s
ctp_chunk_t
*
sctp_make_datafrag_empty
(
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_datafrag_empty
(
struct
sctp_association
*
asoc
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
data_len
,
__u8
flags
,
__u16
ssn
)
int
data_len
,
__u8
flags
,
__u16
ssn
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
s
ctp_datahdr_t
dp
;
s
truct
sctp_datahdr
dp
;
int
chunk_len
;
int
chunk_len
;
/* We assign the TSN as LATE as possible, not here when
/* We assign the TSN as LATE as possible, not here when
* creating the chunk.
* creating the chunk.
*/
*/
dp
.
tsn
=
1000000
;
/* This marker is a debugging aid. */
dp
.
tsn
=
0
;
dp
.
stream
=
htons
(
sinfo
->
sinfo_stream
);
dp
.
stream
=
htons
(
sinfo
->
sinfo_stream
);
dp
.
ppid
=
htonl
(
sinfo
->
sinfo_ppid
);
dp
.
ppid
=
htonl
(
sinfo
->
sinfo_ppid
);
dp
.
ssn
=
htons
(
ssn
);
/* Set the flags for an unordered send. */
/* Set the flags for an unordered send. */
if
(
sinfo
->
sinfo_flags
&
MSG_UNORDERED
)
if
(
sinfo
->
sinfo_flags
&
MSG_UNORDERED
)
{
flags
|=
SCTP_DATA_UNORDERED
;
flags
|=
SCTP_DATA_UNORDERED
;
dp
.
ssn
=
0
;
}
else
dp
.
ssn
=
htons
(
ssn
);
chunk_len
=
sizeof
(
dp
)
+
data_len
;
chunk_len
=
sizeof
(
dp
)
+
data_len
;
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_DATA
,
flags
,
chunk_len
);
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_DATA
,
flags
,
chunk_len
);
...
@@ -535,12 +537,12 @@ sctp_chunk_t *sctp_make_datafrag_empty(struct sctp_association *asoc,
...
@@ -535,12 +537,12 @@ sctp_chunk_t *sctp_make_datafrag_empty(struct sctp_association *asoc,
/* Make a DATA chunk for the given association. Populate the data
/* Make a DATA chunk for the given association. Populate the data
* payload.
* payload.
*/
*/
s
ctp_chunk_t
*
sctp_make_datafrag
(
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_datafrag
(
struct
sctp_association
*
asoc
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
data_len
,
const
__u8
*
data
,
int
data_len
,
const
__u8
*
data
,
__u8
flags
,
__u16
ssn
)
__u8
flags
,
__u16
ssn
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
retval
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
data_len
,
flags
,
ssn
);
retval
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
data_len
,
flags
,
ssn
);
if
(
retval
)
if
(
retval
)
...
@@ -552,11 +554,11 @@ sctp_chunk_t *sctp_make_datafrag(struct sctp_association *asoc,
...
@@ -552,11 +554,11 @@ sctp_chunk_t *sctp_make_datafrag(struct sctp_association *asoc,
/* Make a DATA chunk for the given association to ride on stream id
/* Make a DATA chunk for the given association to ride on stream id
* 'stream', with a payload id of 'payload', and a body of 'data'.
* 'stream', with a payload id of 'payload', and a body of 'data'.
*/
*/
s
ctp_chunk_t
*
sctp_make_data
(
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_data
(
struct
sctp_association
*
asoc
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
data_len
,
const
__u8
*
data
)
int
data_len
,
const
__u8
*
data
)
{
{
s
ctp_chunk_t
*
retval
=
NULL
;
s
truct
sctp_chunk
*
retval
=
NULL
;
retval
=
sctp_make_data_empty
(
asoc
,
sinfo
,
data_len
);
retval
=
sctp_make_data_empty
(
asoc
,
sinfo
,
data_len
);
if
(
retval
)
if
(
retval
)
...
@@ -569,7 +571,7 @@ sctp_chunk_t *sctp_make_data(struct sctp_association *asoc,
...
@@ -569,7 +571,7 @@ sctp_chunk_t *sctp_make_data(struct sctp_association *asoc,
* hold 'data_len' octets of data. We use this version when we need
* hold 'data_len' octets of data. We use this version when we need
* to build the message AFTER allocating memory.
* to build the message AFTER allocating memory.
*/
*/
s
ctp_chunk_t
*
sctp_make_data_empty
(
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_data_empty
(
struct
sctp_association
*
asoc
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
data_len
)
int
data_len
)
{
{
...
@@ -582,9 +584,9 @@ sctp_chunk_t *sctp_make_data_empty(struct sctp_association *asoc,
...
@@ -582,9 +584,9 @@ sctp_chunk_t *sctp_make_data_empty(struct sctp_association *asoc,
* association. This reports on which TSN's we've seen to date,
* association. This reports on which TSN's we've seen to date,
* including duplicates and gaps.
* including duplicates and gaps.
*/
*/
s
ctp_chunk_t
*
sctp_make_sack
(
const
struct
sctp_association
*
asoc
)
s
truct
sctp_chunk
*
sctp_make_sack
(
const
struct
sctp_association
*
asoc
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
sctp_sackhdr_t
sack
;
sctp_sackhdr_t
sack
;
sctp_gap_ack_block_t
gab
;
sctp_gap_ack_block_t
gab
;
int
length
;
int
length
;
...
@@ -679,9 +681,9 @@ sctp_chunk_t *sctp_make_sack(const struct sctp_association *asoc)
...
@@ -679,9 +681,9 @@ sctp_chunk_t *sctp_make_sack(const struct sctp_association *asoc)
}
}
/* Make a SHUTDOWN chunk. */
/* Make a SHUTDOWN chunk. */
s
ctp_chunk_t
*
sctp_make_shutdown
(
const
struct
sctp_association
*
asoc
)
s
truct
sctp_chunk
*
sctp_make_shutdown
(
const
struct
sctp_association
*
asoc
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
sctp_shutdownhdr_t
shut
;
sctp_shutdownhdr_t
shut
;
__u32
ctsn
;
__u32
ctsn
;
...
@@ -699,10 +701,10 @@ sctp_chunk_t *sctp_make_shutdown(const struct sctp_association *asoc)
...
@@ -699,10 +701,10 @@ sctp_chunk_t *sctp_make_shutdown(const struct sctp_association *asoc)
return
retval
;
return
retval
;
}
}
s
ctp_chunk_t
*
sctp_make_shutdown_ack
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_shutdown_ack
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
)
const
s
truct
sctp_chunk
*
chunk
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_SHUTDOWN_ACK
,
0
,
0
);
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_SHUTDOWN_ACK
,
0
,
0
);
...
@@ -721,10 +723,11 @@ sctp_chunk_t *sctp_make_shutdown_ack(const struct sctp_association *asoc,
...
@@ -721,10 +723,11 @@ sctp_chunk_t *sctp_make_shutdown_ack(const struct sctp_association *asoc,
return
retval
;
return
retval
;
}
}
sctp_chunk_t
*
sctp_make_shutdown_complete
(
const
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
sctp_make_shutdown_complete
(
const
sctp_chunk_t
*
chunk
)
const
struct
sctp_association
*
asoc
,
const
struct
sctp_chunk
*
chunk
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
__u8
flags
=
0
;
__u8
flags
=
0
;
/* Maybe set the T-bit if we have no association. */
/* Maybe set the T-bit if we have no association. */
...
@@ -751,11 +754,11 @@ sctp_chunk_t *sctp_make_shutdown_complete(const struct sctp_association *asoc,
...
@@ -751,11 +754,11 @@ sctp_chunk_t *sctp_make_shutdown_complete(const struct sctp_association *asoc,
/* Create an ABORT. Note that we set the T bit if we have no
/* Create an ABORT. Note that we set the T bit if we have no
* association.
* association.
*/
*/
s
ctp_chunk_t
*
sctp_make_abort
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_abort
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
,
const
s
truct
sctp_chunk
*
chunk
,
const
size_t
hint
)
const
size_t
hint
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
__u8
flags
=
0
;
__u8
flags
=
0
;
/* Maybe set the T-bit if we have no association. */
/* Maybe set the T-bit if we have no association. */
...
@@ -779,10 +782,11 @@ sctp_chunk_t *sctp_make_abort(const struct sctp_association *asoc,
...
@@ -779,10 +782,11 @@ sctp_chunk_t *sctp_make_abort(const struct sctp_association *asoc,
}
}
/* Helper to create ABORT with a NO_USER_DATA error. */
/* Helper to create ABORT with a NO_USER_DATA error. */
sctp_chunk_t
*
sctp_make_abort_no_data
(
const
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
sctp_make_abort_no_data
(
const
sctp_chunk_t
*
chunk
,
__u32
tsn
)
const
struct
sctp_association
*
asoc
,
const
struct
sctp_chunk
*
chunk
,
__u32
tsn
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
__u32
payload
;
__u32
payload
;
retval
=
sctp_make_abort
(
asoc
,
chunk
,
sizeof
(
sctp_errhdr_t
)
retval
=
sctp_make_abort
(
asoc
,
chunk
,
sizeof
(
sctp_errhdr_t
)
...
@@ -813,11 +817,11 @@ sctp_chunk_t *sctp_make_abort_no_data(const struct sctp_association *asoc,
...
@@ -813,11 +817,11 @@ sctp_chunk_t *sctp_make_abort_no_data(const struct sctp_association *asoc,
}
}
/* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */
/* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */
s
ctp_chunk_t
*
sctp_make_abort_user
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_abort_user
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
,
const
s
truct
sctp_chunk
*
chunk
,
const
struct
msghdr
*
msg
)
const
struct
msghdr
*
msg
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
void
*
payload
=
NULL
,
*
payoff
;
void
*
payload
=
NULL
,
*
payoff
;
size_t
paylen
;
size_t
paylen
;
struct
iovec
*
iov
=
msg
->
msg_iov
;
struct
iovec
*
iov
=
msg
->
msg_iov
;
...
@@ -853,18 +857,18 @@ sctp_chunk_t *sctp_make_abort_user(const struct sctp_association *asoc,
...
@@ -853,18 +857,18 @@ sctp_chunk_t *sctp_make_abort_user(const struct sctp_association *asoc,
err_copy:
err_copy:
kfree
(
payload
);
kfree
(
payload
);
err_payload:
err_payload:
sctp_
free_chunk
(
retval
);
sctp_
chunk_free
(
retval
);
retval
=
NULL
;
retval
=
NULL
;
err_chunk:
err_chunk:
return
retval
;
return
retval
;
}
}
/* Make a HEARTBEAT chunk. */
/* Make a HEARTBEAT chunk. */
s
ctp_chunk_t
*
sctp_make_heartbeat
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_heartbeat
(
const
struct
sctp_association
*
asoc
,
const
struct
sctp_transport
*
transport
,
const
struct
sctp_transport
*
transport
,
const
void
*
payload
,
const
size_t
paylen
)
const
void
*
payload
,
const
size_t
paylen
)
{
{
s
ctp_chunk_t
*
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_HEARTBEAT
,
s
truct
sctp_chunk
*
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_HEARTBEAT
,
0
,
paylen
);
0
,
paylen
);
if
(
!
retval
)
if
(
!
retval
)
...
@@ -880,15 +884,16 @@ sctp_chunk_t *sctp_make_heartbeat(const struct sctp_association *asoc,
...
@@ -880,15 +884,16 @@ sctp_chunk_t *sctp_make_heartbeat(const struct sctp_association *asoc,
return
retval
;
return
retval
;
}
}
s
ctp_chunk_t
*
sctp_make_heartbeat_ack
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_heartbeat_ack
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
,
const
s
truct
sctp_chunk
*
chunk
,
const
void
*
payload
,
const
size_t
paylen
)
const
void
*
payload
,
const
size_t
paylen
)
{
{
sctp_chunk_t
*
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_HEARTBEAT_ACK
,
struct
sctp_chunk
*
retval
;
0
,
paylen
);
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_HEARTBEAT_ACK
,
0
,
paylen
);
if
(
!
retval
)
if
(
!
retval
)
goto
nodata
;
goto
nodata
;
retval
->
subh
.
hbs_hdr
=
sctp_addto_chunk
(
retval
,
paylen
,
payload
);
retval
->
subh
.
hbs_hdr
=
sctp_addto_chunk
(
retval
,
paylen
,
payload
);
/* RFC 2960 6.4 Multi-homed SCTP Endpoints
/* RFC 2960 6.4 Multi-homed SCTP Endpoints
...
@@ -910,11 +915,12 @@ sctp_chunk_t *sctp_make_heartbeat_ack(const struct sctp_association *asoc,
...
@@ -910,11 +915,12 @@ sctp_chunk_t *sctp_make_heartbeat_ack(const struct sctp_association *asoc,
/* Create an Operation Error chunk with the specified space reserved.
/* Create an Operation Error chunk with the specified space reserved.
* This routine can be used for containing multiple causes in the chunk.
* This routine can be used for containing multiple causes in the chunk.
*/
*/
sctp_chunk_t
*
sctp_make_op_error_space
(
const
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
sctp_make_op_error_space
(
const
sctp_chunk_t
*
chunk
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_chunk
*
chunk
,
size_t
size
)
size_t
size
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_ERROR
,
0
,
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_ERROR
,
0
,
sizeof
(
sctp_errhdr_t
)
+
size
);
sizeof
(
sctp_errhdr_t
)
+
size
);
...
@@ -937,13 +943,14 @@ sctp_chunk_t *sctp_make_op_error_space(const struct sctp_association *asoc,
...
@@ -937,13 +943,14 @@ sctp_chunk_t *sctp_make_op_error_space(const struct sctp_association *asoc,
}
}
/* Create an Operation Error chunk. */
/* Create an Operation Error chunk. */
s
ctp_chunk_t
*
sctp_make_op_error
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_op_error
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
,
const
s
truct
sctp_chunk
*
chunk
,
__u16
cause_code
,
const
void
*
payload
,
__u16
cause_code
,
const
void
*
payload
,
size_t
paylen
)
size_t
paylen
)
{
{
s
ctp_chunk_t
*
retval
=
sctp_make_op_error_space
(
asoc
,
chunk
,
paylen
)
;
s
truct
sctp_chunk
*
retval
;
retval
=
sctp_make_op_error_space
(
asoc
,
chunk
,
paylen
);
if
(
!
retval
)
if
(
!
retval
)
goto
nodata
;
goto
nodata
;
...
@@ -960,15 +967,15 @@ sctp_chunk_t *sctp_make_op_error(const struct sctp_association *asoc,
...
@@ -960,15 +967,15 @@ sctp_chunk_t *sctp_make_op_error(const struct sctp_association *asoc,
/* Turn an skb into a chunk.
/* Turn an skb into a chunk.
* FIXME: Eventually move the structure directly inside the skb->cb[].
* FIXME: Eventually move the structure directly inside the skb->cb[].
*/
*/
s
ctp_chunk_t
*
sctp_chunkify
(
struct
sk_buff
*
skb
,
s
truct
sctp_chunk
*
sctp_chunkify
(
struct
sk_buff
*
skb
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
struct
sock
*
sk
)
struct
sock
*
sk
)
{
{
s
ctp_chunk_t
*
retval
=
t_new
(
sctp_chunk_t
,
GFP_ATOMIC
);
s
truct
sctp_chunk
*
retval
=
t_new
(
struct
sctp_chunk
,
GFP_ATOMIC
);
if
(
!
retval
)
if
(
!
retval
)
goto
nodata
;
goto
nodata
;
memset
(
retval
,
0
,
sizeof
(
s
ctp_chunk_t
));
memset
(
retval
,
0
,
sizeof
(
s
truct
sctp_chunk
));
if
(
!
sk
)
{
if
(
!
sk
)
{
SCTP_DEBUG_PRINTK
(
"chunkifying skb %p w/o an sk
\n
"
,
skb
);
SCTP_DEBUG_PRINTK
(
"chunkifying skb %p w/o an sk
\n
"
,
skb
);
...
@@ -976,7 +983,7 @@ sctp_chunk_t *sctp_chunkify(struct sk_buff *skb,
...
@@ -976,7 +983,7 @@ sctp_chunk_t *sctp_chunkify(struct sk_buff *skb,
retval
->
skb
=
skb
;
retval
->
skb
=
skb
;
retval
->
asoc
=
(
struct
sctp_association
*
)
asoc
;
retval
->
asoc
=
(
struct
sctp_association
*
)
asoc
;
retval
->
num_times_sent
=
0
;
retval
->
resent
=
0
;
retval
->
has_tsn
=
0
;
retval
->
has_tsn
=
0
;
retval
->
has_ssn
=
0
;
retval
->
has_ssn
=
0
;
retval
->
rtt_in_progress
=
0
;
retval
->
rtt_in_progress
=
0
;
...
@@ -996,17 +1003,24 @@ sctp_chunk_t *sctp_chunkify(struct sk_buff *skb,
...
@@ -996,17 +1003,24 @@ sctp_chunk_t *sctp_chunkify(struct sk_buff *skb,
retval
->
tsn_gap_acked
=
0
;
retval
->
tsn_gap_acked
=
0
;
retval
->
fast_retransmit
=
0
;
retval
->
fast_retransmit
=
0
;
/* If this is a fragmented message, track all fragments
* of the message (for SEND_FAILED).
*/
retval
->
msg
=
NULL
;
/* Polish the bead hole. */
/* Polish the bead hole. */
INIT_LIST_HEAD
(
&
retval
->
transmitted_list
);
INIT_LIST_HEAD
(
&
retval
->
transmitted_list
);
INIT_LIST_HEAD
(
&
retval
->
frag_list
);
INIT_LIST_HEAD
(
&
retval
->
frag_list
);
SCTP_DBG_OBJCNT_INC
(
chunk
);
SCTP_DBG_OBJCNT_INC
(
chunk
);
atomic_set
(
&
retval
->
refcnt
,
1
);
nodata:
nodata:
return
retval
;
return
retval
;
}
}
/* Set chunk->source and dest based on the IP header in chunk->skb. */
/* Set chunk->source and dest based on the IP header in chunk->skb. */
void
sctp_init_addrs
(
s
ctp_chunk_t
*
chunk
,
union
sctp_addr
*
src
,
void
sctp_init_addrs
(
s
truct
sctp_chunk
*
chunk
,
union
sctp_addr
*
src
,
union
sctp_addr
*
dest
)
union
sctp_addr
*
dest
)
{
{
memcpy
(
&
chunk
->
source
,
src
,
sizeof
(
union
sctp_addr
));
memcpy
(
&
chunk
->
source
,
src
,
sizeof
(
union
sctp_addr
));
...
@@ -1014,7 +1028,7 @@ void sctp_init_addrs(sctp_chunk_t *chunk, union sctp_addr *src,
...
@@ -1014,7 +1028,7 @@ void sctp_init_addrs(sctp_chunk_t *chunk, union sctp_addr *src,
}
}
/* Extract the source address from a chunk. */
/* Extract the source address from a chunk. */
const
union
sctp_addr
*
sctp_source
(
const
s
ctp_chunk_t
*
chunk
)
const
union
sctp_addr
*
sctp_source
(
const
s
truct
sctp_chunk
*
chunk
)
{
{
/* If we have a known transport, use that. */
/* If we have a known transport, use that. */
if
(
chunk
->
transport
)
{
if
(
chunk
->
transport
)
{
...
@@ -1028,10 +1042,10 @@ const union sctp_addr *sctp_source(const sctp_chunk_t *chunk)
...
@@ -1028,10 +1042,10 @@ const union sctp_addr *sctp_source(const sctp_chunk_t *chunk)
/* Create a new chunk, setting the type and flags headers from the
/* Create a new chunk, setting the type and flags headers from the
* arguments, reserving enough space for a 'paylen' byte payload.
* arguments, reserving enough space for a 'paylen' byte payload.
*/
*/
s
ctp_chunk_t
*
sctp_make_chunk
(
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
sctp_make_chunk
(
const
struct
sctp_association
*
asoc
,
__u8
type
,
__u8
flags
,
int
paylen
)
__u8
type
,
__u8
flags
,
int
paylen
)
{
{
s
ctp_chunk_t
*
retval
;
s
truct
sctp_chunk
*
retval
;
sctp_chunkhdr_t
*
chunk_hdr
;
sctp_chunkhdr_t
*
chunk_hdr
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
struct
sock
*
sk
;
struct
sock
*
sk
;
...
@@ -1067,12 +1081,10 @@ sctp_chunk_t *sctp_make_chunk(const struct sctp_association *asoc,
...
@@ -1067,12 +1081,10 @@ sctp_chunk_t *sctp_make_chunk(const struct sctp_association *asoc,
return
NULL
;
return
NULL
;
}
}
/* Release the memory occupied by a chunk. */
/* Release the memory occupied by a chunk. */
void
sctp_free_chunk
(
sctp_chunk_t
*
chunk
)
static
void
sctp_chunk_destroy
(
struct
sctp_chunk
*
chunk
)
{
{
/* Make sure that we are not on any list. */
skb_unlink
((
struct
sk_buff
*
)
chunk
);
list_del
(
&
chunk
->
transmitted_list
);
/* Free the chunk skb data and the SCTP_chunk stub itself. */
/* Free the chunk skb data and the SCTP_chunk stub itself. */
dev_kfree_skb
(
chunk
->
skb
);
dev_kfree_skb
(
chunk
->
skb
);
...
@@ -1081,11 +1093,37 @@ void sctp_free_chunk(sctp_chunk_t *chunk)
...
@@ -1081,11 +1093,37 @@ void sctp_free_chunk(sctp_chunk_t *chunk)
SCTP_DBG_OBJCNT_DEC
(
chunk
);
SCTP_DBG_OBJCNT_DEC
(
chunk
);
}
}
/* Possibly, free the chunk. */
void
sctp_chunk_free
(
struct
sctp_chunk
*
chunk
)
{
/* Make sure that we are not on any list. */
skb_unlink
((
struct
sk_buff
*
)
chunk
);
list_del
(
&
chunk
->
transmitted_list
);
/* Release our reference on the message tracker. */
if
(
chunk
->
msg
)
sctp_datamsg_put
(
chunk
->
msg
);
sctp_chunk_put
(
chunk
);
}
/* Grab a reference to the chunk. */
void
sctp_chunk_hold
(
struct
sctp_chunk
*
ch
)
{
atomic_inc
(
&
ch
->
refcnt
);
}
/* Release a reference to the chunk. */
void
sctp_chunk_put
(
struct
sctp_chunk
*
ch
)
{
if
(
atomic_dec_and_test
(
&
ch
->
refcnt
))
sctp_chunk_destroy
(
ch
);
}
/* Append bytes to the end of a chunk. Will panic if chunk is not big
/* Append bytes to the end of a chunk. Will panic if chunk is not big
* enough.
* enough.
*/
*/
void
*
sctp_addto_chunk
(
s
ctp_chunk_t
*
chunk
,
int
len
,
const
void
*
data
)
void
*
sctp_addto_chunk
(
s
truct
sctp_chunk
*
chunk
,
int
len
,
const
void
*
data
)
{
{
void
*
target
;
void
*
target
;
void
*
padding
;
void
*
padding
;
...
@@ -1109,7 +1147,7 @@ void *sctp_addto_chunk(sctp_chunk_t *chunk, int len, const void *data)
...
@@ -1109,7 +1147,7 @@ void *sctp_addto_chunk(sctp_chunk_t *chunk, int len, const void *data)
* chunk is not big enough.
* chunk is not big enough.
* Returns a kernel err value.
* Returns a kernel err value.
*/
*/
static
int
sctp_user_addto_chunk
(
sctp_chunk_t
*
chunk
,
int
off
,
int
len
,
int
sctp_user_addto_chunk
(
struct
sctp_chunk
*
chunk
,
int
off
,
int
len
,
struct
iovec
*
data
)
struct
iovec
*
data
)
{
{
__u8
*
target
;
__u8
*
target
;
...
@@ -1131,132 +1169,10 @@ static int sctp_user_addto_chunk(sctp_chunk_t *chunk, int off, int len,
...
@@ -1131,132 +1169,10 @@ static int sctp_user_addto_chunk(sctp_chunk_t *chunk, int off, int len,
return
err
;
return
err
;
}
}
/* A data chunk can have a maximum payload of (2^16 - 20). Break
* down any such message into smaller chunks. Opportunistically, fragment
* the chunks down to the current MTU constraints. We may get refragmented
* later if the PMTU changes, but it is _much better_ to fragment immediately
* with a reasonable guess than always doing our fragmentation on the
* soft-interrupt.
*/
int
sctp_datachunks_from_user
(
struct
sctp_association
*
asoc
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
struct
msghdr
*
msg
,
int
msg_len
,
struct
sk_buff_head
*
chunks
)
{
int
max
,
whole
,
i
,
offset
,
over
,
err
;
int
len
,
first_len
;
sctp_chunk_t
*
chunk
;
__u8
frag
;
/* What is a reasonable fragmentation point right now? */
max
=
asoc
->
pmtu
;
if
(
max
<
SCTP_MIN_PMTU
)
max
=
SCTP_MIN_PMTU
;
max
-=
SCTP_IP_OVERHEAD
;
/* Make sure not beyond maximum chunk size. */
if
(
max
>
SCTP_MAX_CHUNK_LEN
)
max
=
SCTP_MAX_CHUNK_LEN
;
/* Subtract out the overhead of a data chunk header. */
max
-=
sizeof
(
struct
sctp_data_chunk
);
whole
=
0
;
first_len
=
max
;
/* Encourage Cookie-ECHO bundling. */
if
(
asoc
->
state
<
SCTP_STATE_COOKIE_ECHOED
)
{
whole
=
msg_len
/
(
max
-
SCTP_ARBITRARY_COOKIE_ECHO_LEN
);
/* Account for the DATA to be bundled with the COOKIE-ECHO. */
if
(
whole
)
{
first_len
=
max
-
SCTP_ARBITRARY_COOKIE_ECHO_LEN
;
msg_len
-=
first_len
;
whole
=
1
;
}
}
/* How many full sized? How many bytes leftover? */
whole
+=
msg_len
/
max
;
over
=
msg_len
%
max
;
offset
=
0
;
if
(
whole
&&
over
)
SCTP_INC_STATS_USER
(
SctpFragUsrMsgs
);
/* Create chunks for all the full sized DATA chunks. */
for
(
i
=
0
,
len
=
first_len
;
i
<
whole
;
i
++
)
{
frag
=
SCTP_DATA_MIDDLE_FRAG
;
if
(
0
==
i
)
frag
|=
SCTP_DATA_FIRST_FRAG
;
if
((
i
==
(
whole
-
1
))
&&
!
over
)
frag
|=
SCTP_DATA_LAST_FRAG
;
chunk
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
len
,
frag
,
0
);
if
(
!
chunk
)
goto
nomem
;
err
=
sctp_user_addto_chunk
(
chunk
,
offset
,
len
,
msg
->
msg_iov
);
if
(
err
<
0
)
goto
errout
;
offset
+=
len
;
/* Put the chunk->skb back into the form expected by send. */
__skb_pull
(
chunk
->
skb
,
(
__u8
*
)
chunk
->
chunk_hdr
-
(
__u8
*
)
chunk
->
skb
->
data
);
__skb_queue_tail
(
chunks
,
(
struct
sk_buff
*
)
chunk
);
/* The first chunk, the first chunk was likely short
* to allow bundling, so reset to full size.
*/
if
(
0
==
i
)
len
=
max
;
}
/* .. now the leftover bytes. */
if
(
over
)
{
if
(
!
whole
)
frag
=
SCTP_DATA_NOT_FRAG
;
else
frag
=
SCTP_DATA_LAST_FRAG
;
chunk
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
over
,
frag
,
0
);
if
(
!
chunk
)
goto
nomem
;
err
=
sctp_user_addto_chunk
(
chunk
,
offset
,
over
,
msg
->
msg_iov
);
/* Put the chunk->skb back into the form expected by send. */
__skb_pull
(
chunk
->
skb
,
(
__u8
*
)
chunk
->
chunk_hdr
-
(
__u8
*
)
chunk
->
skb
->
data
);
if
(
err
<
0
)
goto
errout
;
__skb_queue_tail
(
chunks
,
(
struct
sk_buff
*
)
chunk
);
}
err
=
0
;
goto
out
;
nomem:
err
=
-
ENOMEM
;
errout:
while
((
chunk
=
(
sctp_chunk_t
*
)
__skb_dequeue
(
chunks
)))
sctp_free_chunk
(
chunk
);
out:
return
err
;
}
/* Helper function to assign a TSN if needed. This assumes that both
/* Helper function to assign a TSN if needed. This assumes that both
* the data_hdr and association have already been assigned.
* the data_hdr and association have already been assigned.
*/
*/
void
sctp_chunk_assign_ssn
(
s
ctp_chunk_t
*
chunk
)
void
sctp_chunk_assign_ssn
(
s
truct
sctp_chunk
*
chunk
)
{
{
__u16
ssn
;
__u16
ssn
;
__u16
sid
;
__u16
sid
;
...
@@ -1283,7 +1199,7 @@ void sctp_chunk_assign_ssn(sctp_chunk_t *chunk)
...
@@ -1283,7 +1199,7 @@ void sctp_chunk_assign_ssn(sctp_chunk_t *chunk)
/* Helper function to assign a TSN if needed. This assumes that both
/* Helper function to assign a TSN if needed. This assumes that both
* the data_hdr and association have already been assigned.
* the data_hdr and association have already been assigned.
*/
*/
void
sctp_chunk_assign_tsn
(
s
ctp_chunk_t
*
chunk
)
void
sctp_chunk_assign_tsn
(
s
truct
sctp_chunk
*
chunk
)
{
{
if
(
!
chunk
->
has_tsn
)
{
if
(
!
chunk
->
has_tsn
)
{
/* This is the last possible instant to
/* This is the last possible instant to
...
@@ -1347,7 +1263,7 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
...
@@ -1347,7 +1263,7 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
*/
*/
sctp_cookie_param_t
*
sctp_pack_cookie
(
const
struct
sctp_endpoint
*
ep
,
sctp_cookie_param_t
*
sctp_pack_cookie
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
init_chunk
,
const
s
truct
sctp_chunk
*
init_chunk
,
int
*
cookie_len
,
int
*
cookie_len
,
const
__u8
*
raw_addrs
,
int
addrs_len
)
const
__u8
*
raw_addrs
,
int
addrs_len
)
{
{
...
@@ -1424,8 +1340,8 @@ sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
...
@@ -1424,8 +1340,8 @@ sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
struct
sctp_association
*
sctp_unpack_cookie
(
struct
sctp_association
*
sctp_unpack_cookie
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
chunk
,
int
gfp
,
s
truct
sctp_chunk
*
chunk
,
int
gfp
,
int
*
error
,
s
ctp_chunk_t
**
errp
)
int
*
error
,
s
truct
sctp_chunk
**
errp
)
{
{
struct
sctp_association
*
retval
=
NULL
;
struct
sctp_association
*
retval
=
NULL
;
sctp_signed_cookie_t
*
cookie
;
sctp_signed_cookie_t
*
cookie
;
...
@@ -1579,8 +1495,8 @@ struct __sctp_missing {
...
@@ -1579,8 +1495,8 @@ struct __sctp_missing {
*/
*/
static
int
sctp_process_missing_param
(
const
struct
sctp_association
*
asoc
,
static
int
sctp_process_missing_param
(
const
struct
sctp_association
*
asoc
,
sctp_param_t
paramtype
,
sctp_param_t
paramtype
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
s
ctp_chunk_t
**
errp
)
s
truct
sctp_chunk
**
errp
)
{
{
struct
__sctp_missing
report
;
struct
__sctp_missing
report
;
__u16
len
;
__u16
len
;
...
@@ -1606,8 +1522,8 @@ static int sctp_process_missing_param(const struct sctp_association *asoc,
...
@@ -1606,8 +1522,8 @@ static int sctp_process_missing_param(const struct sctp_association *asoc,
/* Report an Invalid Mandatory Parameter. */
/* Report an Invalid Mandatory Parameter. */
static
int
sctp_process_inv_mandatory
(
const
struct
sctp_association
*
asoc
,
static
int
sctp_process_inv_mandatory
(
const
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
s
ctp_chunk_t
**
errp
)
s
truct
sctp_chunk
**
errp
)
{
{
/* Invalid Mandatory Parameter Error has no payload. */
/* Invalid Mandatory Parameter Error has no payload. */
...
@@ -1626,8 +1542,8 @@ static int sctp_process_inv_mandatory(const struct sctp_association *asoc,
...
@@ -1626,8 +1542,8 @@ static int sctp_process_inv_mandatory(const struct sctp_association *asoc,
*/
*/
static
int
sctp_process_hn_param
(
const
struct
sctp_association
*
asoc
,
static
int
sctp_process_hn_param
(
const
struct
sctp_association
*
asoc
,
union
sctp_params
param
,
union
sctp_params
param
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
s
ctp_chunk_t
**
errp
)
s
truct
sctp_chunk
**
errp
)
{
{
__u16
len
=
ntohs
(
param
.
p
->
length
);
__u16
len
=
ntohs
(
param
.
p
->
length
);
...
@@ -1671,8 +1587,8 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
...
@@ -1671,8 +1587,8 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
*/
*/
static
int
sctp_process_unk_param
(
const
struct
sctp_association
*
asoc
,
static
int
sctp_process_unk_param
(
const
struct
sctp_association
*
asoc
,
union
sctp_params
param
,
union
sctp_params
param
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
s
ctp_chunk_t
**
errp
)
s
truct
sctp_chunk
**
errp
)
{
{
int
retval
=
1
;
int
retval
=
1
;
...
@@ -1734,8 +1650,8 @@ static int sctp_process_unk_param(const struct sctp_association *asoc,
...
@@ -1734,8 +1650,8 @@ static int sctp_process_unk_param(const struct sctp_association *asoc,
static
int
sctp_verify_param
(
const
struct
sctp_association
*
asoc
,
static
int
sctp_verify_param
(
const
struct
sctp_association
*
asoc
,
union
sctp_params
param
,
union
sctp_params
param
,
sctp_cid_t
cid
,
sctp_cid_t
cid
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
s
ctp_chunk_t
**
err_chunk
)
s
truct
sctp_chunk
**
err_chunk
)
{
{
int
retval
=
1
;
int
retval
=
1
;
...
@@ -1772,8 +1688,8 @@ static int sctp_verify_param(const struct sctp_association *asoc,
...
@@ -1772,8 +1688,8 @@ static int sctp_verify_param(const struct sctp_association *asoc,
int
sctp_verify_init
(
const
struct
sctp_association
*
asoc
,
int
sctp_verify_init
(
const
struct
sctp_association
*
asoc
,
sctp_cid_t
cid
,
sctp_cid_t
cid
,
sctp_init_chunk_t
*
peer_init
,
sctp_init_chunk_t
*
peer_init
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
s
ctp_chunk_t
**
errp
)
s
truct
sctp_chunk
**
errp
)
{
{
union
sctp_params
param
;
union
sctp_params
param
;
int
has_cookie
=
0
;
int
has_cookie
=
0
;
...
...
net/sctp/sm_sideeffect.c
View file @
6cf4b403
...
@@ -81,11 +81,11 @@ static void sctp_do_ecn_ce_work(struct sctp_association *asoc,
...
@@ -81,11 +81,11 @@ static void sctp_do_ecn_ce_work(struct sctp_association *asoc,
* This element represents the lowest TSN number in the datagram
* This element represents the lowest TSN number in the datagram
* that was originally marked with the CE bit.
* that was originally marked with the CE bit.
*/
*/
static
s
ctp_chunk_t
*
sctp_do_ecn_ecne_work
(
struct
sctp_association
*
asoc
,
static
s
truct
sctp_chunk
*
sctp_do_ecn_ecne_work
(
struct
sctp_association
*
asoc
,
__u32
lowest_tsn
,
__u32
lowest_tsn
,
s
ctp_chunk_t
*
chunk
)
s
truct
sctp_chunk
*
chunk
)
{
{
s
ctp_chunk_t
*
repl
;
s
truct
sctp_chunk
*
repl
;
/* Our previously transmitted packet ran into some congestion
/* Our previously transmitted packet ran into some congestion
* so we should take action by reducing cwnd and ssthresh
* so we should take action by reducing cwnd and ssthresh
...
@@ -528,7 +528,7 @@ static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds,
...
@@ -528,7 +528,7 @@ static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds,
static
void
sctp_cmd_transport_on
(
sctp_cmd_seq_t
*
cmds
,
static
void
sctp_cmd_transport_on
(
sctp_cmd_seq_t
*
cmds
,
struct
sctp_association
*
asoc
,
struct
sctp_association
*
asoc
,
struct
sctp_transport
*
t
,
struct
sctp_transport
*
t
,
s
ctp_chunk_t
*
chunk
)
s
truct
sctp_chunk
*
chunk
)
{
{
sctp_sender_hb_info_t
*
hbinfo
;
sctp_sender_hb_info_t
*
hbinfo
;
...
@@ -596,7 +596,7 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
...
@@ -596,7 +596,7 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
*/
*/
static
void
sctp_cmd_setup_t2
(
sctp_cmd_seq_t
*
cmds
,
static
void
sctp_cmd_setup_t2
(
sctp_cmd_seq_t
*
cmds
,
struct
sctp_association
*
asoc
,
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
chunk
)
s
truct
sctp_chunk
*
chunk
)
{
{
struct
sctp_transport
*
t
;
struct
sctp_transport
*
t
;
...
@@ -836,8 +836,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
...
@@ -836,8 +836,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
int
error
=
0
;
int
error
=
0
;
int
force
;
int
force
;
sctp_cmd_t
*
cmd
;
sctp_cmd_t
*
cmd
;
s
ctp_chunk_t
*
new_obj
;
s
truct
sctp_chunk
*
new_obj
;
s
ctp_chunk_t
*
chunk
=
NULL
;
s
truct
sctp_chunk
*
chunk
=
NULL
;
struct
sctp_packet
*
packet
;
struct
sctp_packet
*
packet
;
struct
list_head
*
pos
;
struct
list_head
*
pos
;
struct
timer_list
*
timer
;
struct
timer_list
*
timer
;
...
@@ -845,8 +845,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
...
@@ -845,8 +845,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
struct
sctp_transport
*
t
;
struct
sctp_transport
*
t
;
sctp_sackhdr_t
sackh
;
sctp_sackhdr_t
sackh
;
if
(
SCTP_EVENT_T_TIMEOUT
!=
event_type
)
if
(
SCTP_EVENT_T_TIMEOUT
!=
event_type
)
chunk
=
(
s
ctp_chunk_t
*
)
event_arg
;
chunk
=
(
s
truct
sctp_chunk
*
)
event_arg
;
/* Note: This whole file is a huge candidate for rework.
/* Note: This whole file is a huge candidate for rework.
* For example, each command could either have its own handler, so
* For example, each command could either have its own handler, so
...
@@ -935,7 +935,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
...
@@ -935,7 +935,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
new_obj
=
sctp_make_cookie_echo
(
asoc
,
chunk
);
new_obj
=
sctp_make_cookie_echo
(
asoc
,
chunk
);
if
(
!
new_obj
)
{
if
(
!
new_obj
)
{
if
(
cmd
->
obj
.
ptr
)
if
(
cmd
->
obj
.
ptr
)
sctp_
free_chunk
(
cmd
->
obj
.
ptr
);
sctp_
chunk_free
(
cmd
->
obj
.
ptr
);
goto
nomem
;
goto
nomem
;
}
}
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
...
...
net/sctp/sm_statefuns.c
View file @
6cf4b403
...
@@ -101,7 +101,7 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
...
@@ -101,7 +101,7 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
struct
sctp_ulpevent
*
ev
;
struct
sctp_ulpevent
*
ev
;
/* RFC 2960 6.10 Bundling
/* RFC 2960 6.10 Bundling
...
@@ -185,10 +185,10 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
...
@@ -185,10 +185,10 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
s
ctp_chunk_t
*
repl
;
s
truct
sctp_chunk
*
repl
;
struct
sctp_association
*
new_asoc
;
struct
sctp_association
*
new_asoc
;
s
ctp_chunk_t
*
err_chunk
;
s
truct
sctp_chunk
*
err_chunk
;
struct
sctp_packet
*
packet
;
struct
sctp_packet
*
packet
;
sctp_unrecognized_param_t
*
unk_param
;
sctp_unrecognized_param_t
*
unk_param
;
struct
sock
*
sk
;
struct
sock
*
sk
;
...
@@ -232,7 +232,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
...
@@ -232,7 +232,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
ntohs
(
err_chunk
->
chunk_hdr
->
length
)
-
ntohs
(
err_chunk
->
chunk_hdr
->
length
)
-
sizeof
(
sctp_chunkhdr_t
));
sizeof
(
sctp_chunkhdr_t
));
sctp_
free_chunk
(
err_chunk
);
sctp_
chunk_free
(
err_chunk
);
if
(
packet
)
{
if
(
packet
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SEND_PKT
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SEND_PKT
,
...
@@ -303,7 +303,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
...
@@ -303,7 +303,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
* parameter type.
* parameter type.
*/
*/
sctp_addto_chunk
(
repl
,
len
,
unk_param
);
sctp_addto_chunk
(
repl
,
len
,
unk_param
);
sctp_
free_chunk
(
err_chunk
);
sctp_
chunk_free
(
err_chunk
);
}
}
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
...
@@ -320,7 +320,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
...
@@ -320,7 +320,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
nomem_ack:
nomem_ack:
if
(
err_chunk
)
if
(
err_chunk
)
sctp_
free_chunk
(
err_chunk
);
sctp_
chunk_free
(
err_chunk
);
nomem_init:
nomem_init:
sctp_association_free
(
new_asoc
);
sctp_association_free
(
new_asoc
);
nomem:
nomem:
...
@@ -361,10 +361,10 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
...
@@ -361,10 +361,10 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
sctp_init_chunk_t
*
initchunk
;
sctp_init_chunk_t
*
initchunk
;
__u32
init_tag
;
__u32
init_tag
;
s
ctp_chunk_t
*
err_chunk
;
s
truct
sctp_chunk
*
err_chunk
;
struct
sctp_packet
*
packet
;
struct
sctp_packet
*
packet
;
sctp_disposition_t
ret
;
sctp_disposition_t
ret
;
...
@@ -386,7 +386,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
...
@@ -386,7 +386,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
* error and close the association by transmitting an ABORT.
* error and close the association by transmitting an ABORT.
*/
*/
if
(
!
init_tag
)
{
if
(
!
init_tag
)
{
s
ctp_chunk_t
*
reply
=
sctp_make_abort
(
asoc
,
chunk
,
0
);
s
truct
sctp_chunk
*
reply
=
sctp_make_abort
(
asoc
,
chunk
,
0
);
if
(
!
reply
)
if
(
!
reply
)
goto
nomem
;
goto
nomem
;
...
@@ -416,7 +416,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
...
@@ -416,7 +416,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
ntohs
(
err_chunk
->
chunk_hdr
->
length
)
-
ntohs
(
err_chunk
->
chunk_hdr
->
length
)
-
sizeof
(
sctp_chunkhdr_t
));
sizeof
(
sctp_chunkhdr_t
));
sctp_
free_chunk
(
err_chunk
);
sctp_
chunk_free
(
err_chunk
);
if
(
packet
)
{
if
(
packet
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SEND_PKT
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SEND_PKT
,
...
@@ -519,13 +519,13 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
...
@@ -519,13 +519,13 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
const
sctp_subtype_t
type
,
void
*
arg
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
struct
sctp_association
*
new_asoc
;
struct
sctp_association
*
new_asoc
;
sctp_init_chunk_t
*
peer_init
;
sctp_init_chunk_t
*
peer_init
;
s
ctp_chunk_t
*
repl
;
s
truct
sctp_chunk
*
repl
;
struct
sctp_ulpevent
*
ev
;
struct
sctp_ulpevent
*
ev
;
int
error
=
0
;
int
error
=
0
;
s
ctp_chunk_t
*
err_chk_p
;
s
truct
sctp_chunk
*
err_chk_p
;
/* If the packet is an OOTB packet which is temporarily on the
/* If the packet is an OOTB packet which is temporarily on the
* control endpoint, respond with an ABORT.
* control endpoint, respond with an ABORT.
...
@@ -623,7 +623,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
...
@@ -623,7 +623,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
nomem_ev:
nomem_ev:
sctp_
free_chunk
(
repl
);
sctp_
chunk_free
(
repl
);
nomem_repl:
nomem_repl:
nomem_init:
nomem_init:
sctp_association_free
(
new_asoc
);
sctp_association_free
(
new_asoc
);
...
@@ -704,7 +704,7 @@ sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
...
@@ -704,7 +704,7 @@ sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
struct
sctp_transport
*
transport
=
(
struct
sctp_transport
*
)
arg
;
struct
sctp_transport
*
transport
=
(
struct
sctp_transport
*
)
arg
;
s
ctp_chunk_t
*
reply
;
s
truct
sctp_chunk
*
reply
;
sctp_sender_hb_info_t
hbinfo
;
sctp_sender_hb_info_t
hbinfo
;
size_t
paylen
=
0
;
size_t
paylen
=
0
;
...
@@ -801,8 +801,8 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
...
@@ -801,8 +801,8 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
s
ctp_chunk_t
*
reply
;
s
truct
sctp_chunk
*
reply
;
size_t
paylen
=
0
;
size_t
paylen
=
0
;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
...
@@ -868,7 +868,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
...
@@ -868,7 +868,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
union
sctp_addr
from_addr
;
union
sctp_addr
from_addr
;
struct
sctp_transport
*
link
;
struct
sctp_transport
*
link
;
sctp_sender_hb_info_t
*
hbinfo
;
sctp_sender_hb_info_t
*
hbinfo
;
...
@@ -919,7 +919,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
...
@@ -919,7 +919,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
* condition.
* condition.
*/
*/
static
int
sctp_sf_send_restart_abort
(
union
sctp_addr
*
ssa
,
static
int
sctp_sf_send_restart_abort
(
union
sctp_addr
*
ssa
,
s
ctp_chunk_t
*
init
,
s
truct
sctp_chunk
*
init
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
int
len
;
int
len
;
...
@@ -971,7 +971,7 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
...
@@ -971,7 +971,7 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
*/
*/
static
int
sctp_sf_check_restart_addrs
(
const
struct
sctp_association
*
new_asoc
,
static
int
sctp_sf_check_restart_addrs
(
const
struct
sctp_association
*
new_asoc
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
init
,
s
truct
sctp_chunk
*
init
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
struct
sctp_transport
*
new_addr
,
*
addr
;
struct
sctp_transport
*
new_addr
,
*
addr
;
...
@@ -1112,10 +1112,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
...
@@ -1112,10 +1112,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
{
sctp_disposition_t
retval
;
sctp_disposition_t
retval
;
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
s
ctp_chunk_t
*
repl
;
s
truct
sctp_chunk
*
repl
;
struct
sctp_association
*
new_asoc
;
struct
sctp_association
*
new_asoc
;
s
ctp_chunk_t
*
err_chunk
;
s
truct
sctp_chunk
*
err_chunk
;
struct
sctp_packet
*
packet
;
struct
sctp_packet
*
packet
;
sctp_unrecognized_param_t
*
unk_param
;
sctp_unrecognized_param_t
*
unk_param
;
int
len
;
int
len
;
...
@@ -1238,7 +1238,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
...
@@ -1238,7 +1238,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
* parameter type.
* parameter type.
*/
*/
sctp_addto_chunk
(
repl
,
len
,
unk_param
);
sctp_addto_chunk
(
repl
,
len
,
unk_param
);
sctp_
free_chunk
(
err_chunk
);
sctp_
chunk_free
(
err_chunk
);
}
}
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_ASOC
,
SCTP_ASOC
(
new_asoc
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_ASOC
,
SCTP_ASOC
(
new_asoc
));
...
@@ -1254,7 +1254,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
...
@@ -1254,7 +1254,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
cleanup:
cleanup:
if
(
err_chunk
)
if
(
err_chunk
)
sctp_
free_chunk
(
err_chunk
);
sctp_
chunk_free
(
err_chunk
);
return
retval
;
return
retval
;
nomem:
nomem:
retval
=
SCTP_DISPOSITION_NOMEM
;
retval
=
SCTP_DISPOSITION_NOMEM
;
...
@@ -1377,13 +1377,13 @@ sctp_disposition_t sctp_sf_do_5_2_2_dupinit(const struct sctp_endpoint *ep,
...
@@ -1377,13 +1377,13 @@ sctp_disposition_t sctp_sf_do_5_2_2_dupinit(const struct sctp_endpoint *ep,
*/
*/
static
sctp_disposition_t
sctp_sf_do_dupcook_a
(
const
struct
sctp_endpoint
*
ep
,
static
sctp_disposition_t
sctp_sf_do_dupcook_a
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
sctp_cmd_seq_t
*
commands
,
sctp_cmd_seq_t
*
commands
,
struct
sctp_association
*
new_asoc
)
struct
sctp_association
*
new_asoc
)
{
{
sctp_init_chunk_t
*
peer_init
;
sctp_init_chunk_t
*
peer_init
;
struct
sctp_ulpevent
*
ev
;
struct
sctp_ulpevent
*
ev
;
s
ctp_chunk_t
*
repl
;
s
truct
sctp_chunk
*
repl
;
/* new_asoc is a brand-new association, so these are not yet
/* new_asoc is a brand-new association, so these are not yet
* side effects--it is safe to run them here.
* side effects--it is safe to run them here.
...
@@ -1429,7 +1429,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
...
@@ -1429,7 +1429,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
nomem_ev:
nomem_ev:
sctp_
free_chunk
(
repl
);
sctp_
chunk_free
(
repl
);
nomem:
nomem:
return
SCTP_DISPOSITION_NOMEM
;
return
SCTP_DISPOSITION_NOMEM
;
}
}
...
@@ -1444,13 +1444,13 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
...
@@ -1444,13 +1444,13 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
/* This case represents an initialization collision. */
/* This case represents an initialization collision. */
static
sctp_disposition_t
sctp_sf_do_dupcook_b
(
const
struct
sctp_endpoint
*
ep
,
static
sctp_disposition_t
sctp_sf_do_dupcook_b
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
sctp_cmd_seq_t
*
commands
,
sctp_cmd_seq_t
*
commands
,
struct
sctp_association
*
new_asoc
)
struct
sctp_association
*
new_asoc
)
{
{
sctp_init_chunk_t
*
peer_init
;
sctp_init_chunk_t
*
peer_init
;
struct
sctp_ulpevent
*
ev
;
struct
sctp_ulpevent
*
ev
;
s
ctp_chunk_t
*
repl
;
s
truct
sctp_chunk
*
repl
;
/* new_asoc is a brand-new association, so these are not yet
/* new_asoc is a brand-new association, so these are not yet
* side effects--it is safe to run them here.
* side effects--it is safe to run them here.
...
@@ -1492,7 +1492,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
...
@@ -1492,7 +1492,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
nomem_ev:
nomem_ev:
sctp_
free_chunk
(
repl
);
sctp_
chunk_free
(
repl
);
nomem:
nomem:
return
SCTP_DISPOSITION_NOMEM
;
return
SCTP_DISPOSITION_NOMEM
;
}
}
...
@@ -1508,7 +1508,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
...
@@ -1508,7 +1508,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
/* This case represents an intialization collision. */
/* This case represents an intialization collision. */
static
sctp_disposition_t
sctp_sf_do_dupcook_c
(
const
struct
sctp_endpoint
*
ep
,
static
sctp_disposition_t
sctp_sf_do_dupcook_c
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
sctp_cmd_seq_t
*
commands
,
sctp_cmd_seq_t
*
commands
,
struct
sctp_association
*
new_asoc
)
struct
sctp_association
*
new_asoc
)
{
{
...
@@ -1529,12 +1529,12 @@ static sctp_disposition_t sctp_sf_do_dupcook_c(const struct sctp_endpoint *ep,
...
@@ -1529,12 +1529,12 @@ static sctp_disposition_t sctp_sf_do_dupcook_c(const struct sctp_endpoint *ep,
/* This case represents an intialization collision. */
/* This case represents an intialization collision. */
static
sctp_disposition_t
sctp_sf_do_dupcook_d
(
const
struct
sctp_endpoint
*
ep
,
static
sctp_disposition_t
sctp_sf_do_dupcook_d
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
sctp_cmd_seq_t
*
commands
,
sctp_cmd_seq_t
*
commands
,
struct
sctp_association
*
new_asoc
)
struct
sctp_association
*
new_asoc
)
{
{
struct
sctp_ulpevent
*
ev
=
NULL
;
struct
sctp_ulpevent
*
ev
=
NULL
;
s
ctp_chunk_t
*
repl
;
s
truct
sctp_chunk
*
repl
;
/* Clarification from Implementor's Guide:
/* Clarification from Implementor's Guide:
* D) When both local and remote tags match the endpoint should
* D) When both local and remote tags match the endpoint should
...
@@ -1610,11 +1610,11 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
...
@@ -1610,11 +1610,11 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
sctp_disposition_t
retval
;
sctp_disposition_t
retval
;
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
struct
sctp_association
*
new_asoc
;
struct
sctp_association
*
new_asoc
;
int
error
=
0
;
int
error
=
0
;
char
action
;
char
action
;
s
ctp_chunk_t
*
err_chk_p
;
s
truct
sctp_chunk
*
err_chk_p
;
/* "Decode" the chunk. We have no optional parameters so we
/* "Decode" the chunk. We have no optional parameters so we
* are in good shape.
* are in good shape.
...
@@ -1708,7 +1708,7 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(
...
@@ -1708,7 +1708,7 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
if
(
!
sctp_vtag_verify_either
(
chunk
,
asoc
))
if
(
!
sctp_vtag_verify_either
(
chunk
,
asoc
))
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
...
@@ -1731,7 +1731,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
...
@@ -1731,7 +1731,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
if
(
!
sctp_vtag_verify_either
(
chunk
,
asoc
))
if
(
!
sctp_vtag_verify_either
(
chunk
,
asoc
))
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
...
@@ -1785,7 +1785,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
...
@@ -1785,7 +1785,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
sctp_errhdr_t
*
err
;
sctp_errhdr_t
*
err
;
err
=
(
sctp_errhdr_t
*
)(
chunk
->
skb
->
data
);
err
=
(
sctp_errhdr_t
*
)(
chunk
->
skb
->
data
);
...
@@ -1839,14 +1839,14 @@ sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
...
@@ -1839,14 +1839,14 @@ sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
time_t
stale
;
time_t
stale
;
sctp_cookie_preserve_param_t
bht
;
sctp_cookie_preserve_param_t
bht
;
sctp_errhdr_t
*
err
;
sctp_errhdr_t
*
err
;
struct
list_head
*
pos
;
struct
list_head
*
pos
;
struct
sctp_transport
*
t
;
struct
sctp_transport
*
t
;
s
ctp_chunk_t
*
reply
;
s
truct
sctp_chunk
*
reply
;
s
ctp_bind_addr_t
*
bp
;
s
truct
sctp_bind_addr
*
bp
;
int
attempts
;
int
attempts
;
attempts
=
asoc
->
counters
[
SCTP_COUNTER_INIT_ERROR
]
+
1
;
attempts
=
asoc
->
counters
[
SCTP_COUNTER_INIT_ERROR
]
+
1
;
...
@@ -1881,7 +1881,7 @@ sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
...
@@ -1881,7 +1881,7 @@ sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
bht
.
lifespan_increment
=
htonl
(
stale
);
bht
.
lifespan_increment
=
htonl
(
stale
);
/* Build that new INIT chunk. */
/* Build that new INIT chunk. */
bp
=
(
s
ctp_bind_addr_t
*
)
&
asoc
->
base
.
bind_addr
;
bp
=
(
s
truct
sctp_bind_addr
*
)
&
asoc
->
base
.
bind_addr
;
reply
=
sctp_make_init
(
asoc
,
bp
,
GFP_ATOMIC
,
sizeof
(
bht
));
reply
=
sctp_make_init
(
asoc
,
bp
,
GFP_ATOMIC
,
sizeof
(
bht
));
if
(
!
reply
)
if
(
!
reply
)
goto
nomem
;
goto
nomem
;
...
@@ -1954,7 +1954,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
...
@@ -1954,7 +1954,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
__u16
error
=
SCTP_ERROR_NO_ERROR
;
__u16
error
=
SCTP_ERROR_NO_ERROR
;
if
(
!
sctp_vtag_verify_either
(
chunk
,
asoc
))
if
(
!
sctp_vtag_verify_either
(
chunk
,
asoc
))
...
@@ -1985,7 +1985,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
...
@@ -1985,7 +1985,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
__u16
error
=
SCTP_ERROR_NO_ERROR
;
__u16
error
=
SCTP_ERROR_NO_ERROR
;
if
(
!
sctp_vtag_verify_either
(
chunk
,
asoc
))
if
(
!
sctp_vtag_verify_either
(
chunk
,
asoc
))
...
@@ -2064,7 +2064,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
...
@@ -2064,7 +2064,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
sctp_shutdownhdr_t
*
sdh
;
sctp_shutdownhdr_t
*
sdh
;
sctp_disposition_t
disposition
;
sctp_disposition_t
disposition
;
...
@@ -2119,8 +2119,8 @@ sctp_disposition_t sctp_sf_do_9_2_reshutack(const struct sctp_endpoint *ep,
...
@@ -2119,8 +2119,8 @@ sctp_disposition_t sctp_sf_do_9_2_reshutack(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
(
sctp_chunk_t
*
)
arg
;
s
truct
sctp_chunk
*
chunk
=
(
struct
sctp_chunk
*
)
arg
;
s
ctp_chunk_t
*
reply
;
s
truct
sctp_chunk
*
reply
;
reply
=
sctp_make_shutdown_ack
(
asoc
,
chunk
);
reply
=
sctp_make_shutdown_ack
(
asoc
,
chunk
);
if
(
NULL
==
reply
)
if
(
NULL
==
reply
)
...
@@ -2174,7 +2174,7 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
...
@@ -2174,7 +2174,7 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
sctp_cwrhdr_t
*
cwr
;
sctp_cwrhdr_t
*
cwr
;
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* that the value in the Verification Tag field of the
...
@@ -2230,7 +2230,7 @@ sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep,
...
@@ -2230,7 +2230,7 @@ sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
sctp_ecnehdr_t
*
ecne
;
sctp_ecnehdr_t
*
ecne
;
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* that the value in the Verification Tag field of the
...
@@ -2287,9 +2287,9 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
...
@@ -2287,9 +2287,9 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
sctp_datahdr_t
*
data_hdr
;
sctp_datahdr_t
*
data_hdr
;
s
ctp_chunk_t
*
err
;
s
truct
sctp_chunk
*
err
;
size_t
datalen
;
size_t
datalen
;
sctp_verb_t
deliver
;
sctp_verb_t
deliver
;
int
tmp
;
int
tmp
;
...
@@ -2545,9 +2545,9 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
...
@@ -2545,9 +2545,9 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
sctp_datahdr_t
*
data_hdr
;
sctp_datahdr_t
*
data_hdr
;
s
ctp_chunk_t
*
err
;
s
truct
sctp_chunk
*
err
;
size_t
datalen
;
size_t
datalen
;
int
tmp
;
int
tmp
;
__u32
tsn
;
__u32
tsn
;
...
@@ -2720,7 +2720,7 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
...
@@ -2720,7 +2720,7 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
sctp_sackhdr_t
*
sackh
;
sctp_sackhdr_t
*
sackh
;
__u32
ctsn
;
__u32
ctsn
;
...
@@ -2782,8 +2782,8 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
...
@@ -2782,8 +2782,8 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
struct
sctp_packet
*
packet
=
NULL
;
struct
sctp_packet
*
packet
=
NULL
;
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
s
ctp_chunk_t
*
abort
;
s
truct
sctp_chunk
*
abort
;
packet
=
sctp_ootb_pkt_new
(
asoc
,
chunk
);
packet
=
sctp_ootb_pkt_new
(
asoc
,
chunk
);
...
@@ -2827,7 +2827,7 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
...
@@ -2827,7 +2827,7 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
struct
sctp_ulpevent
*
ev
;
struct
sctp_ulpevent
*
ev
;
while
(
chunk
->
chunk_end
>
chunk
->
skb
->
data
)
{
while
(
chunk
->
chunk_end
>
chunk
->
skb
->
data
)
{
...
@@ -2864,8 +2864,8 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
...
@@ -2864,8 +2864,8 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
s
ctp_chunk_t
*
reply
;
s
truct
sctp_chunk
*
reply
;
struct
sctp_ulpevent
*
ev
;
struct
sctp_ulpevent
*
ev
;
/* 10.2 H) SHUTDOWN COMPLETE notification
/* 10.2 H) SHUTDOWN COMPLETE notification
...
@@ -2932,7 +2932,7 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
...
@@ -2932,7 +2932,7 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
struct
sk_buff
*
skb
=
chunk
->
skb
;
struct
sk_buff
*
skb
=
chunk
->
skb
;
sctp_chunkhdr_t
*
ch
;
sctp_chunkhdr_t
*
ch
;
__u8
*
ch_end
;
__u8
*
ch_end
;
...
@@ -2984,8 +2984,8 @@ sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
...
@@ -2984,8 +2984,8 @@ sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
struct
sctp_packet
*
packet
=
NULL
;
struct
sctp_packet
*
packet
=
NULL
;
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
s
ctp_chunk_t
*
shut
;
s
truct
sctp_chunk
*
shut
;
packet
=
sctp_ootb_pkt_new
(
asoc
,
chunk
);
packet
=
sctp_ootb_pkt_new
(
asoc
,
chunk
);
...
@@ -3069,8 +3069,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
...
@@ -3069,8 +3069,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
unk_chunk
=
arg
;
s
truct
sctp_chunk
*
unk_chunk
=
arg
;
s
ctp_chunk_t
*
err_chunk
;
s
truct
sctp_chunk
*
err_chunk
;
sctp_chunkhdr_t
*
hdr
;
sctp_chunkhdr_t
*
hdr
;
SCTP_DEBUG_PRINTK
(
"Processing the unknown chunk id %d.
\n
"
,
type
.
chunk
);
SCTP_DEBUG_PRINTK
(
"Processing the unknown chunk id %d.
\n
"
,
type
.
chunk
);
...
@@ -3206,7 +3206,7 @@ sctp_disposition_t lucky(const struct sctp_endpoint *ep,
...
@@ -3206,7 +3206,7 @@ sctp_disposition_t lucky(const struct sctp_endpoint *ep,
void *arg,
void *arg,
sctp_cmd_seq_t *commands)
sctp_cmd_seq_t *commands)
{
{
s
ctp_chunk_t
*chunk = arg;
s
truct sctp_chunk
*chunk = arg;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* that the value in the Verification Tag field of the
...
@@ -3243,7 +3243,7 @@ sctp_disposition_t other_stupid(const struct sctp_endpoint *ep,
...
@@ -3243,7 +3243,7 @@ sctp_disposition_t other_stupid(const struct sctp_endpoint *ep,
void *arg,
void *arg,
sctp_cmd_seq_t *commands)
sctp_cmd_seq_t *commands)
{
{
s
ctp_chunk_t
*chunk = arg;
s
truct sctp_chunk
*chunk = arg;
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* that the value in the Verification Tag field of the
...
@@ -3348,7 +3348,7 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
...
@@ -3348,7 +3348,7 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
repl
;
s
truct
sctp_chunk
*
repl
;
/* The comment below says that we enter COOKIE-WAIT AFTER
/* The comment below says that we enter COOKIE-WAIT AFTER
* sending the INIT, but that doesn't actually work in our
* sending the INIT, but that doesn't actually work in our
...
@@ -3454,7 +3454,7 @@ sctp_disposition_t sctp_sf_do_prm_send(const struct sctp_endpoint *ep,
...
@@ -3454,7 +3454,7 @@ sctp_disposition_t sctp_sf_do_prm_send(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
arg
;
s
truct
sctp_chunk
*
chunk
=
arg
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
chunk
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
chunk
));
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
...
@@ -3564,7 +3564,7 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
...
@@ -3564,7 +3564,7 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
* if necessary to fill gaps.
* if necessary to fill gaps.
*/
*/
struct
msghdr
*
msg
=
arg
;
struct
msghdr
*
msg
=
arg
;
s
ctp_chunk_t
*
abort
;
s
truct
sctp_chunk
*
abort
;
sctp_disposition_t
retval
;
sctp_disposition_t
retval
;
retval
=
SCTP_DISPOSITION_CONSUME
;
retval
=
SCTP_DISPOSITION_CONSUME
;
...
@@ -3697,7 +3697,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
...
@@ -3697,7 +3697,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
struct
msghdr
*
msg
=
arg
;
struct
msghdr
*
msg
=
arg
;
s
ctp_chunk_t
*
abort
;
s
truct
sctp_chunk
*
abort
;
sctp_disposition_t
retval
;
sctp_disposition_t
retval
;
/* Stop T1-init timer */
/* Stop T1-init timer */
...
@@ -3909,7 +3909,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
...
@@ -3909,7 +3909,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
reply
;
s
truct
sctp_chunk
*
reply
;
/* Once all its outstanding data has been acknowledged, the
/* Once all its outstanding data has been acknowledged, the
* endpoint shall send a SHUTDOWN chunk to its peer including
* endpoint shall send a SHUTDOWN chunk to its peer including
...
@@ -3971,8 +3971,8 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack(
...
@@ -3971,8 +3971,8 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack(
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
chunk
=
(
sctp_chunk_t
*
)
arg
;
s
truct
sctp_chunk
*
chunk
=
(
struct
sctp_chunk
*
)
arg
;
s
ctp_chunk_t
*
reply
;
s
truct
sctp_chunk
*
reply
;
/* If it has no more outstanding DATA chunks, the SHUTDOWN receiver
/* If it has no more outstanding DATA chunks, the SHUTDOWN receiver
* shall send a SHUTDOWN ACK ...
* shall send a SHUTDOWN ACK ...
...
@@ -4152,8 +4152,8 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep,
...
@@ -4152,8 +4152,8 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
repl
;
s
truct
sctp_chunk
*
repl
;
s
ctp_bind_addr_t
*
bp
;
s
truct
sctp_bind_addr
*
bp
;
sctp_event_timeout_t
timer
=
(
sctp_event_timeout_t
)
arg
;
sctp_event_timeout_t
timer
=
(
sctp_event_timeout_t
)
arg
;
int
timeout
;
int
timeout
;
int
attempts
;
int
attempts
;
...
@@ -4168,7 +4168,7 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep,
...
@@ -4168,7 +4168,7 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep,
(
attempts
<
asoc
->
max_init_attempts
))
{
(
attempts
<
asoc
->
max_init_attempts
))
{
switch
(
timer
)
{
switch
(
timer
)
{
case
SCTP_EVENT_TIMEOUT_T1_INIT
:
case
SCTP_EVENT_TIMEOUT_T1_INIT
:
bp
=
(
s
ctp_bind_addr_t
*
)
&
asoc
->
base
.
bind_addr
;
bp
=
(
s
truct
sctp_bind_addr
*
)
&
asoc
->
base
.
bind_addr
;
repl
=
sctp_make_init
(
asoc
,
bp
,
GFP_ATOMIC
,
0
);
repl
=
sctp_make_init
(
asoc
,
bp
,
GFP_ATOMIC
,
0
);
break
;
break
;
...
@@ -4219,7 +4219,7 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
...
@@ -4219,7 +4219,7 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
reply
=
NULL
;
s
truct
sctp_chunk
*
reply
=
NULL
;
SCTP_DEBUG_PRINTK
(
"Timer T2 expired.
\n
"
);
SCTP_DEBUG_PRINTK
(
"Timer T2 expired.
\n
"
);
if
(
asoc
->
overall_error_count
>=
asoc
->
overall_error_threshold
)
{
if
(
asoc
->
overall_error_count
>=
asoc
->
overall_error_threshold
)
{
...
@@ -4279,7 +4279,7 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep,
...
@@ -4279,7 +4279,7 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_chunk_t
*
reply
=
NULL
;
s
truct
sctp_chunk
*
reply
=
NULL
;
SCTP_DEBUG_PRINTK
(
"Timer T5 expired.
\n
"
);
SCTP_DEBUG_PRINTK
(
"Timer T5 expired.
\n
"
);
...
@@ -4399,7 +4399,7 @@ sctp_disposition_t sctp_sf_timer_ignore(const struct sctp_endpoint *ep,
...
@@ -4399,7 +4399,7 @@ sctp_disposition_t sctp_sf_timer_ignore(const struct sctp_endpoint *ep,
********************************************************************/
********************************************************************/
/* Pull the SACK chunk based on the SACK header. */
/* Pull the SACK chunk based on the SACK header. */
sctp_sackhdr_t
*
sctp_sm_pull_sack
(
s
ctp_chunk_t
*
chunk
)
sctp_sackhdr_t
*
sctp_sm_pull_sack
(
s
truct
sctp_chunk
*
chunk
)
{
{
sctp_sackhdr_t
*
sack
;
sctp_sackhdr_t
*
sack
;
__u16
num_blocks
;
__u16
num_blocks
;
...
@@ -4423,12 +4423,12 @@ sctp_sackhdr_t *sctp_sm_pull_sack(sctp_chunk_t *chunk)
...
@@ -4423,12 +4423,12 @@ sctp_sackhdr_t *sctp_sm_pull_sack(sctp_chunk_t *chunk)
*/
*/
struct
sctp_packet
*
sctp_abort_pkt_new
(
const
struct
sctp_endpoint
*
ep
,
struct
sctp_packet
*
sctp_abort_pkt_new
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
chunk
,
s
truct
sctp_chunk
*
chunk
,
const
void
*
payload
,
const
void
*
payload
,
size_t
paylen
)
size_t
paylen
)
{
{
struct
sctp_packet
*
packet
;
struct
sctp_packet
*
packet
;
s
ctp_chunk_t
*
abort
;
s
truct
sctp_chunk
*
abort
;
packet
=
sctp_ootb_pkt_new
(
asoc
,
chunk
);
packet
=
sctp_ootb_pkt_new
(
asoc
,
chunk
);
...
@@ -4458,7 +4458,7 @@ struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
...
@@ -4458,7 +4458,7 @@ struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
/* Allocate a packet for responding in the OOTB conditions. */
/* Allocate a packet for responding in the OOTB conditions. */
struct
sctp_packet
*
sctp_ootb_pkt_new
(
const
struct
sctp_association
*
asoc
,
struct
sctp_packet
*
sctp_ootb_pkt_new
(
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
)
const
s
truct
sctp_chunk
*
chunk
)
{
{
struct
sctp_packet
*
packet
;
struct
sctp_packet
*
packet
;
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
...
@@ -4524,9 +4524,9 @@ void sctp_ootb_pkt_free(struct sctp_packet *packet)
...
@@ -4524,9 +4524,9 @@ void sctp_ootb_pkt_free(struct sctp_packet *packet)
/* Send a stale cookie error when a invalid COOKIE ECHO chunk is found */
/* Send a stale cookie error when a invalid COOKIE ECHO chunk is found */
void
sctp_send_stale_cookie_err
(
const
struct
sctp_endpoint
*
ep
,
void
sctp_send_stale_cookie_err
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
const
s
ctp_chunk_t
*
chunk
,
const
s
truct
sctp_chunk
*
chunk
,
sctp_cmd_seq_t
*
commands
,
sctp_cmd_seq_t
*
commands
,
s
ctp_chunk_t
*
err_chunk
)
s
truct
sctp_chunk
*
err_chunk
)
{
{
struct
sctp_packet
*
packet
;
struct
sctp_packet
*
packet
;
...
@@ -4540,6 +4540,6 @@ void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
...
@@ -4540,6 +4540,6 @@ void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
SCTP_PACKET
(
packet
));
SCTP_PACKET
(
packet
));
SCTP_INC_STATS
(
SctpOutCtrlChunks
);
SCTP_INC_STATS
(
SctpOutCtrlChunks
);
}
else
}
else
sctp_
free_chunk
(
err_chunk
);
sctp_
chunk_free
(
err_chunk
);
}
}
}
}
net/sctp/socket.c
View file @
6cf4b403
...
@@ -82,7 +82,7 @@
...
@@ -82,7 +82,7 @@
/* Forward declarations for internal helper functions. */
/* Forward declarations for internal helper functions. */
static
int
sctp_writeable
(
struct
sock
*
sk
);
static
int
sctp_writeable
(
struct
sock
*
sk
);
static
inline
int
sctp_wspace
(
struct
sctp_association
*
asoc
);
static
inline
int
sctp_wspace
(
struct
sctp_association
*
asoc
);
static
inline
void
sctp_set_owner_w
(
s
ctp_chunk_t
*
chunk
);
static
inline
void
sctp_set_owner_w
(
s
truct
sctp_chunk
*
chunk
);
static
void
sctp_wfree
(
struct
sk_buff
*
skb
);
static
void
sctp_wfree
(
struct
sk_buff
*
skb
);
static
int
sctp_wait_for_sndbuf
(
struct
sctp_association
*
,
long
*
timeo_p
,
static
int
sctp_wait_for_sndbuf
(
struct
sctp_association
*
,
long
*
timeo_p
,
int
msg_len
);
int
msg_len
);
...
@@ -195,7 +195,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
...
@@ -195,7 +195,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
{
{
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
struct
sctp_endpoint
*
ep
=
sp
->
ep
;
struct
sctp_endpoint
*
ep
=
sp
->
ep
;
s
ctp_bind_addr_t
*
bp
=
&
ep
->
base
.
bind_addr
;
s
truct
sctp_bind_addr
*
bp
=
&
ep
->
base
.
bind_addr
;
struct
sctp_af
*
af
;
struct
sctp_af
*
af
;
unsigned
short
snum
;
unsigned
short
snum
;
int
ret
=
0
;
int
ret
=
0
;
...
@@ -488,7 +488,7 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
...
@@ -488,7 +488,7 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
struct
sctp_endpoint
*
ep
=
sp
->
ep
;
struct
sctp_endpoint
*
ep
=
sp
->
ep
;
int
cnt
;
int
cnt
;
s
ctp_bind_addr_t
*
bp
=
&
ep
->
base
.
bind_addr
;
s
truct
sctp_bind_addr
*
bp
=
&
ep
->
base
.
bind_addr
;
int
retval
=
0
;
int
retval
=
0
;
union
sctp_addr
saveaddr
;
union
sctp_addr
saveaddr
;
...
@@ -769,8 +769,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
...
@@ -769,8 +769,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
struct
sctp_opt
*
sp
;
struct
sctp_opt
*
sp
;
struct
sctp_endpoint
*
ep
;
struct
sctp_endpoint
*
ep
;
struct
sctp_association
*
new_asoc
=
NULL
,
*
asoc
=
NULL
;
struct
sctp_association
*
new_asoc
=
NULL
,
*
asoc
=
NULL
;
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
,
*
chunk_tp
;
s
ctp_chunk_t
*
chunk
=
NULL
;
s
truct
sctp_chunk
*
chunk
=
NULL
;
union
sctp_addr
to
;
union
sctp_addr
to
;
struct
sockaddr
*
msg_name
=
NULL
;
struct
sockaddr
*
msg_name
=
NULL
;
struct
sctp_sndrcvinfo
default_sinfo
=
{
0
};
struct
sctp_sndrcvinfo
default_sinfo
=
{
0
};
...
@@ -782,7 +782,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
...
@@ -782,7 +782,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
sctp_scope_t
scope
;
sctp_scope_t
scope
;
long
timeo
;
long
timeo
;
__u16
sinfo_flags
=
0
;
__u16
sinfo_flags
=
0
;
struct
sk_buff_head
chunks
;
struct
sctp_datamsg
*
datamsg
;
struct
list_head
*
pos
,
*
temp
;
int
msg_flags
=
msg
->
msg_flags
;
int
msg_flags
=
msg
->
msg_flags
;
SCTP_DEBUG_PRINTK
(
"sctp_sendmsg(sk: %p, msg: %p, msg_len: %d)
\n
"
,
SCTP_DEBUG_PRINTK
(
"sctp_sendmsg(sk: %p, msg: %p, msg_len: %d)
\n
"
,
...
@@ -855,12 +856,20 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
...
@@ -855,12 +856,20 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto
out_nounlock
;
goto
out_nounlock
;
}
}
sctp_lock_sock
(
sk
);
/* If MSG_ADDR_OVER is set, there must be an address
* specified in msg_name.
*/
if
((
sinfo_flags
&
MSG_ADDR_OVER
)
&&
(
!
msg
->
msg_name
))
{
err
=
-
EINVAL
;
goto
out_nounlock
;
}
transport
=
NULL
;
transport
=
NULL
;
SCTP_DEBUG_PRINTK
(
"About to look up association.
\n
"
);
SCTP_DEBUG_PRINTK
(
"About to look up association.
\n
"
);
sctp_lock_sock
(
sk
);
/* If a msg_name has been specified, assume this is to be used. */
/* If a msg_name has been specified, assume this is to be used. */
if
(
msg_name
)
{
if
(
msg_name
)
{
/* Look for a matching association on the endpoint. */
/* Look for a matching association on the endpoint. */
...
@@ -1044,11 +1053,25 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
...
@@ -1044,11 +1053,25 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto
out_free
;
goto
out_free
;
}
}
/* This flag, in the UDP model, requests the SCTP stack to
* override the primary destination address with the
* address found with the sendto/sendmsg call.
*/
if
(
sinfo_flags
&
MSG_ADDR_OVER
)
{
chunk_tp
=
sctp_assoc_lookup_paddr
(
asoc
,
&
to
);
if
(
!
chunk_tp
)
{
err
=
-
EINVAL
;
goto
out_free
;
}
}
else
chunk_tp
=
NULL
;
/* Break the message into multiple chunks of maximum size. */
/* Break the message into multiple chunks of maximum size. */
skb_queue_head_init
(
&
chunks
);
datamsg
=
sctp_datamsg_from_user
(
asoc
,
sinfo
,
msg
,
msg_len
);
err
=
sctp_datachunks_from_user
(
asoc
,
sinfo
,
msg
,
msg_len
,
&
chunks
);
if
(
!
datamsg
)
{
if
(
err
)
err
=
-
ENOMEM
;
goto
out_free
;
goto
out_free
;
}
/* Auto-connect, if we aren't connected already. */
/* Auto-connect, if we aren't connected already. */
if
(
SCTP_STATE_CLOSED
==
asoc
->
state
)
{
if
(
SCTP_STATE_CLOSED
==
asoc
->
state
)
{
...
@@ -1059,31 +1082,20 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
...
@@ -1059,31 +1082,20 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
}
}
/* Now send the (possibly) fragmented message. */
/* Now send the (possibly) fragmented message. */
while
((
chunk
=
(
sctp_chunk_t
*
)
__skb_dequeue
(
&
chunks
)))
{
list_for_each_safe
(
pos
,
temp
,
&
datamsg
->
chunks
)
{
chunk
=
list_entry
(
pos
,
struct
sctp_chunk
,
frag_list
);
list_del_init
(
pos
);
/* Do accounting for the write space. */
/* Do accounting for the write space. */
sctp_set_owner_w
(
chunk
);
sctp_set_owner_w
(
chunk
);
/* This flag, in the UDP model, requests the SCTP stack to
chunk
->
transport
=
chunk_tp
;
* override the primary destination address with the
* address found with the sendto/sendmsg call.
*/
if
(
sinfo_flags
&
MSG_ADDR_OVER
)
{
if
(
!
msg
->
msg_name
)
{
err
=
-
EINVAL
;
goto
out_free
;
}
chunk
->
transport
=
sctp_assoc_lookup_paddr
(
asoc
,
&
to
);
if
(
!
chunk
->
transport
)
{
err
=
-
EINVAL
;
goto
out_free
;
}
}
/* Send it to the lower layers. */
/* Send it to the lower layers. */
sctp_primitive_SEND
(
asoc
,
chunk
);
sctp_primitive_SEND
(
asoc
,
chunk
);
SCTP_DEBUG_PRINTK
(
"We sent primitively.
\n
"
);
SCTP_DEBUG_PRINTK
(
"We sent primitively.
\n
"
);
}
}
sctp_datamsg_free
(
datamsg
);
if
(
!
err
)
{
if
(
!
err
)
{
err
=
msg_len
;
err
=
msg_len
;
...
@@ -1099,8 +1111,9 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
...
@@ -1099,8 +1111,9 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
sctp_association_free
(
asoc
);
sctp_association_free
(
asoc
);
out_free_chunk:
out_free_chunk:
/* The datamsg struct will auto-destruct via ref counting. */
if
(
chunk
)
if
(
chunk
)
sctp_
free_chunk
(
chunk
);
sctp_
chunk_free
(
chunk
);
out_unlock:
out_unlock:
sctp_release_sock
(
sk
);
sctp_release_sock
(
sk
);
...
@@ -2243,7 +2256,7 @@ static int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
...
@@ -2243,7 +2256,7 @@ static int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
char
*
optval
,
int
*
optlen
)
char
*
optval
,
int
*
optlen
)
{
{
sctp_assoc_t
id
;
sctp_assoc_t
id
;
s
ctp_bind_addr_t
*
bp
;
s
truct
sctp_bind_addr
*
bp
;
struct
sctp_association
*
asoc
;
struct
sctp_association
*
asoc
;
struct
list_head
*
pos
;
struct
list_head
*
pos
;
int
cnt
=
0
;
int
cnt
=
0
;
...
@@ -2281,7 +2294,7 @@ static int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
...
@@ -2281,7 +2294,7 @@ static int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
static
int
sctp_getsockopt_local_addrs
(
struct
sock
*
sk
,
int
len
,
static
int
sctp_getsockopt_local_addrs
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
char
*
optval
,
int
*
optlen
)
{
{
s
ctp_bind_addr_t
*
bp
;
s
truct
sctp_bind_addr
*
bp
;
struct
sctp_association
*
asoc
;
struct
sctp_association
*
asoc
;
struct
list_head
*
pos
;
struct
list_head
*
pos
;
int
cnt
=
0
;
int
cnt
=
0
;
...
@@ -3269,7 +3282,7 @@ static inline int sctp_wspace(struct sctp_association *asoc)
...
@@ -3269,7 +3282,7 @@ static inline int sctp_wspace(struct sctp_association *asoc)
* destructor in the data chunk skb for the purpose of the sndbuf space
* destructor in the data chunk skb for the purpose of the sndbuf space
* tracking.
* tracking.
*/
*/
static
inline
void
sctp_set_owner_w
(
s
ctp_chunk_t
*
chunk
)
static
inline
void
sctp_set_owner_w
(
s
truct
sctp_chunk
*
chunk
)
{
{
struct
sctp_association
*
asoc
=
chunk
->
asoc
;
struct
sctp_association
*
asoc
=
chunk
->
asoc
;
struct
sock
*
sk
=
asoc
->
base
.
sk
;
struct
sock
*
sk
=
asoc
->
base
.
sk
;
...
@@ -3279,7 +3292,7 @@ static inline void sctp_set_owner_w(sctp_chunk_t *chunk)
...
@@ -3279,7 +3292,7 @@ static inline void sctp_set_owner_w(sctp_chunk_t *chunk)
chunk
->
skb
->
destructor
=
sctp_wfree
;
chunk
->
skb
->
destructor
=
sctp_wfree
;
/* Save the chunk pointer in skb for sctp_wfree to use later. */
/* Save the chunk pointer in skb for sctp_wfree to use later. */
*
((
s
ctp_chunk_t
**
)(
chunk
->
skb
->
cb
))
=
chunk
;
*
((
s
truct
sctp_chunk
**
)(
chunk
->
skb
->
cb
))
=
chunk
;
asoc
->
sndbuf_used
+=
SCTP_DATA_SNDSIZE
(
chunk
);
asoc
->
sndbuf_used
+=
SCTP_DATA_SNDSIZE
(
chunk
);
sk
->
wmem_queued
+=
SCTP_DATA_SNDSIZE
(
chunk
);
sk
->
wmem_queued
+=
SCTP_DATA_SNDSIZE
(
chunk
);
...
@@ -3317,11 +3330,11 @@ static void __sctp_write_space(struct sctp_association *asoc)
...
@@ -3317,11 +3330,11 @@ static void __sctp_write_space(struct sctp_association *asoc)
static
void
sctp_wfree
(
struct
sk_buff
*
skb
)
static
void
sctp_wfree
(
struct
sk_buff
*
skb
)
{
{
struct
sctp_association
*
asoc
;
struct
sctp_association
*
asoc
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
struct
sock
*
sk
;
struct
sock
*
sk
;
/* Get the saved chunk pointer. */
/* Get the saved chunk pointer. */
chunk
=
*
((
s
ctp_chunk_t
**
)(
skb
->
cb
));
chunk
=
*
((
s
truct
sctp_chunk
**
)(
skb
->
cb
));
asoc
=
chunk
->
asoc
;
asoc
=
chunk
->
asoc
;
sk
=
asoc
->
base
.
sk
;
sk
=
asoc
->
base
.
sk
;
asoc
->
sndbuf_used
-=
SCTP_DATA_SNDSIZE
(
chunk
);
asoc
->
sndbuf_used
-=
SCTP_DATA_SNDSIZE
(
chunk
);
...
...
net/sctp/ulpevent.c
View file @
6cf4b403
...
@@ -316,7 +316,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
...
@@ -316,7 +316,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
* error formats.
* error formats.
*/
*/
struct
sctp_ulpevent
*
sctp_ulpevent_make_remote_error
(
struct
sctp_ulpevent
*
sctp_ulpevent_make_remote_error
(
const
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
chunk
,
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
chunk
,
__u16
flags
,
int
gfp
)
__u16
flags
,
int
gfp
)
{
{
struct
sctp_ulpevent
*
event
;
struct
sctp_ulpevent
*
event
;
...
@@ -420,7 +420,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
...
@@ -420,7 +420,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
* 5.3.1.4 SCTP_SEND_FAILED
* 5.3.1.4 SCTP_SEND_FAILED
*/
*/
struct
sctp_ulpevent
*
sctp_ulpevent_make_send_failed
(
struct
sctp_ulpevent
*
sctp_ulpevent_make_send_failed
(
const
struct
sctp_association
*
asoc
,
s
ctp_chunk_t
*
chunk
,
const
struct
sctp_association
*
asoc
,
s
truct
sctp_chunk
*
chunk
,
__u16
flags
,
__u32
error
,
int
gfp
)
__u16
flags
,
__u32
error
,
int
gfp
)
{
{
struct
sctp_ulpevent
*
event
;
struct
sctp_ulpevent
*
event
;
...
@@ -588,7 +588,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
...
@@ -588,7 +588,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
* 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
* 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
*/
*/
struct
sctp_ulpevent
*
sctp_ulpevent_make_rcvmsg
(
struct
sctp_association
*
asoc
,
struct
sctp_ulpevent
*
sctp_ulpevent_make_rcvmsg
(
struct
sctp_association
*
asoc
,
sctp_chunk_t
*
chunk
,
int
gfp
)
struct
sctp_chunk
*
chunk
,
int
gfp
)
{
{
struct
sctp_ulpevent
*
event
;
struct
sctp_ulpevent
*
event
;
struct
sctp_sndrcvinfo
*
info
;
struct
sctp_sndrcvinfo
*
info
;
...
...
net/sctp/ulpqueue.c
View file @
6cf4b403
...
@@ -118,7 +118,7 @@ void sctp_ulpq_free(struct sctp_ulpq *ulpq)
...
@@ -118,7 +118,7 @@ void sctp_ulpq_free(struct sctp_ulpq *ulpq)
}
}
/* Process an incoming DATA chunk. */
/* Process an incoming DATA chunk. */
int
sctp_ulpq_tail_data
(
struct
sctp_ulpq
*
ulpq
,
s
ctp_chunk_t
*
chunk
,
int
sctp_ulpq_tail_data
(
struct
sctp_ulpq
*
ulpq
,
s
truct
sctp_chunk
*
chunk
,
int
gfp
)
int
gfp
)
{
{
struct
sk_buff_head
temp
;
struct
sk_buff_head
temp
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment