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
Kirill Smelkov
linux
Commits
acbabcbe
Commit
acbabcbe
authored
Mar 03, 2003
by
Jon Grimm
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-lksctp.bkbits.net/lksctp-2.5.work
into touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5.work
parents
7cd48512
020fec6e
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
267 additions
and
176 deletions
+267
-176
include/net/sctp/command.h
include/net/sctp/command.h
+8
-8
include/net/sctp/constants.h
include/net/sctp/constants.h
+1
-0
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+3
-13
include/net/sctp/sm.h
include/net/sctp/sm.h
+23
-23
include/net/sctp/structs.h
include/net/sctp/structs.h
+12
-14
include/net/sctp/user.h
include/net/sctp/user.h
+2
-0
net/sctp/output.c
net/sctp/output.c
+56
-34
net/sctp/outqueue.c
net/sctp/outqueue.c
+62
-44
net/sctp/protocol.c
net/sctp/protocol.c
+6
-3
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+1
-1
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+16
-18
net/sctp/socket.c
net/sctp/socket.c
+77
-18
No files found.
include/net/sctp/command.h
View file @
acbabcbe
...
@@ -110,13 +110,13 @@ typedef union {
...
@@ -110,13 +110,13 @@ typedef union {
sctp_event_timeout_t
to
;
sctp_event_timeout_t
to
;
sctp_counter_t
counter
;
sctp_counter_t
counter
;
void
*
ptr
;
void
*
ptr
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
s
ctp_association_t
*
asoc
;
s
truct
sctp_association
*
asoc
;
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
s
ctp_bind_addr_t
*
bp
;
s
truct
sctp_bind_addr
*
bp
;
sctp_init_chunk_t
*
init
;
sctp_init_chunk_t
*
init
;
struct
sctp_ulpevent
*
ulpevent
;
struct
sctp_ulpevent
*
ulpevent
;
s
ctp_packet_
t
*
packet
;
s
truct
sctp_packe
t
*
packet
;
sctp_sackhdr_t
*
sackh
;
sctp_sackhdr_t
*
sackh
;
}
sctp_arg_t
;
}
sctp_arg_t
;
...
@@ -158,13 +158,13 @@ SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state)
...
@@ -158,13 +158,13 @@ SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state)
SCTP_ARG_CONSTRUCTOR
(
COUNTER
,
sctp_counter_t
,
counter
)
SCTP_ARG_CONSTRUCTOR
(
COUNTER
,
sctp_counter_t
,
counter
)
SCTP_ARG_CONSTRUCTOR
(
TO
,
sctp_event_timeout_t
,
to
)
SCTP_ARG_CONSTRUCTOR
(
TO
,
sctp_event_timeout_t
,
to
)
SCTP_ARG_CONSTRUCTOR
(
PTR
,
void
*
,
ptr
)
SCTP_ARG_CONSTRUCTOR
(
PTR
,
void
*
,
ptr
)
SCTP_ARG_CONSTRUCTOR
(
CHUNK
,
s
ctp_chunk_t
*
,
chunk
)
SCTP_ARG_CONSTRUCTOR
(
CHUNK
,
s
truct
sctp_chunk
*
,
chunk
)
SCTP_ARG_CONSTRUCTOR
(
ASOC
,
s
ctp_association_t
*
,
asoc
)
SCTP_ARG_CONSTRUCTOR
(
ASOC
,
s
truct
sctp_association
*
,
asoc
)
SCTP_ARG_CONSTRUCTOR
(
TRANSPORT
,
struct
sctp_transport
*
,
transport
)
SCTP_ARG_CONSTRUCTOR
(
TRANSPORT
,
struct
sctp_transport
*
,
transport
)
SCTP_ARG_CONSTRUCTOR
(
BA
,
s
ctp_bind_addr_t
*
,
bp
)
SCTP_ARG_CONSTRUCTOR
(
BA
,
s
truct
sctp_bind_addr
*
,
bp
)
SCTP_ARG_CONSTRUCTOR
(
PEER_INIT
,
sctp_init_chunk_t
*
,
init
)
SCTP_ARG_CONSTRUCTOR
(
PEER_INIT
,
sctp_init_chunk_t
*
,
init
)
SCTP_ARG_CONSTRUCTOR
(
ULPEVENT
,
struct
sctp_ulpevent
*
,
ulpevent
)
SCTP_ARG_CONSTRUCTOR
(
ULPEVENT
,
struct
sctp_ulpevent
*
,
ulpevent
)
SCTP_ARG_CONSTRUCTOR
(
PACKET
,
s
ctp_packet_
t
*
,
packet
)
SCTP_ARG_CONSTRUCTOR
(
PACKET
,
s
truct
sctp_packe
t
*
,
packet
)
SCTP_ARG_CONSTRUCTOR
(
SACKH
,
sctp_sackhdr_t
*
,
sackh
)
SCTP_ARG_CONSTRUCTOR
(
SACKH
,
sctp_sackhdr_t
*
,
sackh
)
typedef
struct
{
typedef
struct
{
...
...
include/net/sctp/constants.h
View file @
acbabcbe
...
@@ -345,6 +345,7 @@ typedef enum {
...
@@ -345,6 +345,7 @@ typedef enum {
SCTP_XMIT_PMTU_FULL
,
SCTP_XMIT_PMTU_FULL
,
SCTP_XMIT_RWND_FULL
,
SCTP_XMIT_RWND_FULL
,
SCTP_XMIT_MUST_FRAG
,
SCTP_XMIT_MUST_FRAG
,
SCTP_XMIT_NAGLE_DELAY
,
}
sctp_xmit_t
;
}
sctp_xmit_t
;
/* These are the commands for manipulating transports. */
/* These are the commands for manipulating transports. */
...
...
include/net/sctp/sctp.h
View file @
acbabcbe
...
@@ -313,31 +313,21 @@ static inline void sctp_sysctl_unregister(void) { return; }
...
@@ -313,31 +313,21 @@ static inline void sctp_sysctl_unregister(void) { return; }
#endif
#endif
/* Size of Supported Address Parameter for 'x' address types. */
#define SCTP_SAT_LEN(x) (sizeof(struct sctp_paramhdr) + (x) * sizeof(__u16))
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
extern
int
sctp_v6_init
(
void
);
extern
int
sctp_v6_init
(
void
);
extern
void
sctp_v6_exit
(
void
);
extern
void
sctp_v6_exit
(
void
);
static
inline
int
sctp_ipv6_addr_type
(
const
struct
in6_addr
*
addr
)
static
inline
int
sctp_ipv6_addr_type
(
const
struct
in6_addr
*
addr
)
{
{
return
ipv6_addr_type
((
struct
in6_addr
*
)
addr
);
return
ipv6_addr_type
((
struct
in6_addr
*
)
addr
);
}
}
/* Size of Supported Address Parameter for 'x' address types. */
#define SCTP_SAT_LEN(x) (sizeof(struct sctp_paramhdr) + (x) * sizeof(__u16))
/* Note: These V6 macros are obsolescent. */
/* Use this macro to enclose code fragments which are V6-dependent. */
#define SCTP_V6(m...) m
#define SCTP_V6_SUPPORT 1
#else
/* #ifdef defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
#else
/* #ifdef defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
#define sctp_ipv6_addr_type(a) 0
#define sctp_ipv6_addr_type(a) 0
#define SCTP_SAT_LEN (sizeof(sctp_paramhdr_t) + 1 * sizeof(__u16))
#define SCTP_V6(m...)
/* Do nothing. */
#undef SCTP_V6_SUPPORT
static
inline
int
sctp_v6_init
(
void
)
{
return
0
;
}
static
inline
int
sctp_v6_init
(
void
)
{
return
0
;
}
static
inline
void
sctp_v6_exit
(
void
)
{
return
;
}
static
inline
void
sctp_v6_exit
(
void
)
{
return
;
}
...
...
include/net/sctp/sm.h
View file @
acbabcbe
...
@@ -313,18 +313,18 @@ void sctp_generate_t3_rtx_event(unsigned long peer);
...
@@ -313,18 +313,18 @@ 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
(
sctp_chunk_t
*
);
sctp_sackhdr_t
*
sctp_sm_pull_sack
(
sctp_chunk_t
*
);
s
ctp_packet_t
*
sctp_abort_pkt_new
(
const
sctp_endpoint_t
*
ep
,
s
truct
sctp_packet
*
sctp_abort_pkt_new
(
const
struct
sctp_endpoint
*
,
const
sctp_association_t
*
asoc
,
const
struct
sctp_association
*
,
sctp_chunk_t
*
chunk
,
struct
sctp_chunk
*
chunk
,
const
void
*
payload
,
const
void
*
payload
,
size_t
paylen
);
size_t
paylen
);
s
ctp_packet_t
*
sctp_ootb_pkt_new
(
const
sctp_association_t
*
asoc
,
s
truct
sctp_packet
*
sctp_ootb_pkt_new
(
const
struct
sctp_association
*
,
const
sctp_chunk_t
*
chunk
);
const
struct
sctp_chunk
*
);
void
sctp_ootb_pkt_free
(
s
ctp_packet_t
*
packet
);
void
sctp_ootb_pkt_free
(
s
truct
sctp_packet
*
);
sctp_cookie_param_t
*
sctp_cookie_param_t
*
sctp_pack_cookie
(
const
s
ctp_endpoint_t
*
,
const
sctp_association_t
*
,
sctp_pack_cookie
(
const
s
truct
sctp_endpoint
*
,
const
struct
sctp_association
*
,
const
s
ctp_chunk_t
*
,
int
*
cookie_len
,
const
s
truct
sctp_chunk
*
,
int
*
cookie_len
,
const
__u8
*
,
int
addrs_len
);
const
__u8
*
,
int
addrs_len
);
sctp_association_t
*
sctp_unpack_cookie
(
const
sctp_endpoint_t
*
,
sctp_association_t
*
sctp_unpack_cookie
(
const
sctp_endpoint_t
*
,
const
sctp_association_t
*
,
const
sctp_association_t
*
,
...
...
include/net/sctp/structs.h
View file @
acbabcbe
...
@@ -88,7 +88,6 @@ struct sctp_ssnmap;
...
@@ -88,7 +88,6 @@ struct sctp_ssnmap;
typedef
struct
sctp_endpoint
sctp_endpoint_t
;
typedef
struct
sctp_endpoint
sctp_endpoint_t
;
typedef
struct
sctp_association
sctp_association_t
;
typedef
struct
sctp_association
sctp_association_t
;
typedef
struct
sctp_packet
sctp_packet_t
;
typedef
struct
sctp_chunk
sctp_chunk_t
;
typedef
struct
sctp_chunk
sctp_chunk_t
;
typedef
struct
sctp_bind_addr
sctp_bind_addr_t
;
typedef
struct
sctp_bind_addr
sctp_bind_addr_t
;
typedef
struct
sctp_endpoint_common
sctp_endpoint_common_t
;
typedef
struct
sctp_endpoint_common
sctp_endpoint_common_t
;
...
@@ -604,26 +603,26 @@ struct sctp_packet {
...
@@ -604,26 +603,26 @@ struct sctp_packet {
typedef
int
(
sctp_outq_thandler_t
)(
struct
sctp_outq
*
,
void
*
);
typedef
int
(
sctp_outq_thandler_t
)(
struct
sctp_outq
*
,
void
*
);
typedef
int
(
sctp_outq_ehandler_t
)(
struct
sctp_outq
*
);
typedef
int
(
sctp_outq_ehandler_t
)(
struct
sctp_outq
*
);
typedef
s
ctp_packet_
t
*
(
sctp_outq_ohandler_init_t
)
typedef
s
truct
sctp_packe
t
*
(
sctp_outq_ohandler_init_t
)
(
s
ctp_packet_
t
*
,
(
s
truct
sctp_packe
t
*
,
struct
sctp_transport
*
,
struct
sctp_transport
*
,
__u16
sport
,
__u16
sport
,
__u16
dport
);
__u16
dport
);
typedef
s
ctp_packet_
t
*
(
sctp_outq_ohandler_config_t
)
typedef
s
truct
sctp_packe
t
*
(
sctp_outq_ohandler_config_t
)
(
s
ctp_packet_
t
*
,
(
s
truct
sctp_packe
t
*
,
__u32
vtag
,
__u32
vtag
,
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
)(
s
ctp_packet_
t
*
,
typedef
sctp_xmit_t
(
sctp_outq_ohandler_t
)(
s
truct
sctp_packe
t
*
,
sctp_chunk_t
*
);
sctp_chunk_t
*
);
typedef
int
(
sctp_outq_ohandler_force_t
)(
s
ctp_packet_
t
*
);
typedef
int
(
sctp_outq_ohandler_force_t
)(
s
truct
sctp_packe
t
*
);
sctp_outq_ohandler_init_t
sctp_packet_init
;
sctp_outq_ohandler_init_t
sctp_packet_init
;
sctp_outq_ohandler_config_t
sctp_packet_config
;
sctp_outq_ohandler_config_t
sctp_packet_config
;
sctp_outq_ohandler_t
sctp_packet_append_chunk
;
sctp_outq_ohandler_t
sctp_packet_append_chunk
;
sctp_outq_ohandler_t
sctp_packet_transmit_chunk
;
sctp_outq_ohandler_t
sctp_packet_transmit_chunk
;
sctp_outq_ohandler_force_t
sctp_packet_transmit
;
sctp_outq_ohandler_force_t
sctp_packet_transmit
;
void
sctp_packet_free
(
s
ctp_packet_
t
*
);
void
sctp_packet_free
(
s
truct
sctp_packe
t
*
);
/* This represents a remote transport address.
/* This represents a remote transport address.
...
@@ -789,7 +788,7 @@ struct sctp_transport {
...
@@ -789,7 +788,7 @@ struct sctp_transport {
struct
list_head
transmitted
;
struct
list_head
transmitted
;
/* We build bundle-able packets for this transport here. */
/* We build bundle-able packets for this transport here. */
s
ctp_packet_
t
packet
;
s
truct
sctp_packe
t
packet
;
/* This is the list of transports that have chunks to send. */
/* This is the list of transports that have chunks to send. */
struct
list_head
send_ready
;
struct
list_head
send_ready
;
...
@@ -865,12 +864,11 @@ void sctp_inq_set_th_handler(struct sctp_inq *, void (*)(void *), void *);
...
@@ -865,12 +864,11 @@ void sctp_inq_set_th_handler(struct sctp_inq *, void (*)(void *), void *);
struct
sctp_outq
{
struct
sctp_outq
{
sctp_association_t
*
asoc
;
sctp_association_t
*
asoc
;
/* BUG: This really should be an array of streams.
/* Data pending that has never been transmitted. */
* This really holds a list of chunks (one stream).
* FIXME: If true, why so?
*/
struct
sk_buff_head
out
;
struct
sk_buff_head
out
;
unsigned
out_qlen
;
/* Total length of queued data chunks. */
/* These are control chunks we want to send. */
/* These are control chunks we want to send. */
struct
sk_buff_head
control
;
struct
sk_buff_head
control
;
...
@@ -885,7 +883,7 @@ struct sctp_outq {
...
@@ -885,7 +883,7 @@ struct sctp_outq {
struct
list_head
retransmit
;
struct
list_head
retransmit
;
/* Call these functions to send chunks down to the next lower
/* Call these functions to send chunks down to the next lower
* layer. This is always
SCTP
_packet, but we separate the two
* layer. This is always
sctp
_packet, but we separate the two
* structures to make testing simpler.
* structures to make testing simpler.
*/
*/
sctp_outq_ohandler_init_t
*
init_output
;
sctp_outq_ohandler_init_t
*
init_output
;
...
...
include/net/sctp/user.h
View file @
acbabcbe
...
@@ -108,6 +108,8 @@ enum sctp_optname {
...
@@ -108,6 +108,8 @@ enum sctp_optname {
#define SCTP_GET_LOCAL_ADDRS_NUM SCTP_GET_LOCAL_ADDRS_NUM
#define SCTP_GET_LOCAL_ADDRS_NUM SCTP_GET_LOCAL_ADDRS_NUM
SCTP_GET_LOCAL_ADDRS
,
/* Get all local addresss. */
SCTP_GET_LOCAL_ADDRS
,
/* Get all local addresss. */
#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS
#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS
SCTP_NODELAY
,
/* Get/set nodelay option. */
#define SCTP_NODELAY SCTP_NODELAY
};
};
...
...
net/sctp/output.c
View file @
acbabcbe
...
@@ -62,16 +62,15 @@
...
@@ -62,16 +62,15 @@
#include <net/sctp/sm.h>
#include <net/sctp/sm.h>
/* Forward declarations for private helpers. */
/* Forward declarations for private helpers. */
static
void
sctp_packet_reset
(
s
ctp_packet_
t
*
packet
);
static
void
sctp_packet_reset
(
s
truct
sctp_packe
t
*
packet
);
static
sctp_xmit_t
sctp_packet_append_data
(
s
ctp_packet_
t
*
packet
,
static
sctp_xmit_t
sctp_packet_append_data
(
s
truct
sctp_packe
t
*
packet
,
s
ctp_chunk_t
*
chunk
);
s
truct
sctp_chunk
*
chunk
);
/* Config a packet.
/* Config a packet.
* This appears to be a followup set of initializations.)
* This appears to be a followup set of initializations.)
*/
*/
sctp_packet_t
*
sctp_packet_config
(
sctp_packet_t
*
packet
,
struct
sctp_packet
*
sctp_packet_config
(
struct
sctp_packet
*
packet
,
__u32
vtag
,
__u32
vtag
,
int
ecn_capable
,
int
ecn_capable
,
sctp_packet_phandler_t
*
prepend_handler
)
sctp_packet_phandler_t
*
prepend_handler
)
{
{
int
packet_empty
=
(
packet
->
size
==
SCTP_IP_OVERHEAD
);
int
packet_empty
=
(
packet
->
size
==
SCTP_IP_OVERHEAD
);
...
@@ -89,10 +88,9 @@ sctp_packet_t *sctp_packet_config(sctp_packet_t *packet,
...
@@ -89,10 +88,9 @@ sctp_packet_t *sctp_packet_config(sctp_packet_t *packet,
}
}
/* Initialize the packet structure. */
/* Initialize the packet structure. */
s
ctp_packet_t
*
sctp_packet_init
(
sctp_packet_
t
*
packet
,
s
truct
sctp_packet
*
sctp_packet_init
(
struct
sctp_packe
t
*
packet
,
struct
sctp_transport
*
transport
,
struct
sctp_transport
*
transport
,
__u16
sport
,
__u16
sport
,
__u16
dport
)
__u16
dport
)
{
{
packet
->
transport
=
transport
;
packet
->
transport
=
transport
;
packet
->
source_port
=
sport
;
packet
->
source_port
=
sport
;
...
@@ -109,14 +107,12 @@ sctp_packet_t *sctp_packet_init(sctp_packet_t *packet,
...
@@ -109,14 +107,12 @@ sctp_packet_t *sctp_packet_init(sctp_packet_t *packet,
}
}
/* Free a packet. */
/* Free a packet. */
void
sctp_packet_free
(
s
ctp_packet_
t
*
packet
)
void
sctp_packet_free
(
s
truct
sctp_packe
t
*
packet
)
{
{
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
while
(
NULL
!=
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
)))
(
chunk
=
(
sctp_chunk_t
*
)
skb_dequeue
(
&
packet
->
chunks
)))
{
sctp_free_chunk
(
chunk
);
sctp_free_chunk
(
chunk
);
}
if
(
packet
->
malloced
)
if
(
packet
->
malloced
)
kfree
(
packet
);
kfree
(
packet
);
...
@@ -129,8 +125,8 @@ void sctp_packet_free(sctp_packet_t *packet)
...
@@ -129,8 +125,8 @@ void sctp_packet_free(sctp_packet_t *packet)
* as it can fit in the packet, but any more data that does not fit in this
* as it can fit in the packet, but any more data that does not fit in this
* packet can be sent only after receiving the COOKIE_ACK.
* packet can be sent only after receiving the COOKIE_ACK.
*/
*/
sctp_xmit_t
sctp_packet_transmit_chunk
(
s
ctp_packet_
t
*
packet
,
sctp_xmit_t
sctp_packet_transmit_chunk
(
s
truct
sctp_packe
t
*
packet
,
s
ctp_chunk_t
*
chunk
)
s
truct
sctp_chunk
*
chunk
)
{
{
sctp_xmit_t
retval
;
sctp_xmit_t
retval
;
int
error
=
0
;
int
error
=
0
;
...
@@ -152,6 +148,7 @@ sctp_xmit_t sctp_packet_transmit_chunk(sctp_packet_t *packet,
...
@@ -152,6 +148,7 @@ sctp_xmit_t sctp_packet_transmit_chunk(sctp_packet_t *packet,
case
SCTP_XMIT_MUST_FRAG
:
case
SCTP_XMIT_MUST_FRAG
:
case
SCTP_XMIT_RWND_FULL
:
case
SCTP_XMIT_RWND_FULL
:
case
SCTP_XMIT_OK
:
case
SCTP_XMIT_OK
:
case
SCTP_XMIT_NAGLE_DELAY
:
break
;
break
;
};
};
...
@@ -161,7 +158,8 @@ sctp_xmit_t sctp_packet_transmit_chunk(sctp_packet_t *packet,
...
@@ -161,7 +158,8 @@ sctp_xmit_t sctp_packet_transmit_chunk(sctp_packet_t *packet,
/* Append a chunk to the offered packet reporting back any inability to do
/* Append a chunk to the offered packet reporting back any inability to do
* so.
* so.
*/
*/
sctp_xmit_t
sctp_packet_append_chunk
(
sctp_packet_t
*
packet
,
sctp_chunk_t
*
chunk
)
sctp_xmit_t
sctp_packet_append_chunk
(
struct
sctp_packet
*
packet
,
struct
sctp_chunk
*
chunk
)
{
{
sctp_xmit_t
retval
=
SCTP_XMIT_OK
;
sctp_xmit_t
retval
=
SCTP_XMIT_OK
;
__u16
chunk_len
=
WORD_ROUND
(
ntohs
(
chunk
->
chunk_hdr
->
length
));
__u16
chunk_len
=
WORD_ROUND
(
ntohs
(
chunk
->
chunk_hdr
->
length
));
...
@@ -223,7 +221,7 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
...
@@ -223,7 +221,7 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
}
}
/* It is OK to send this chunk. */
/* It is OK to send this chunk. */
skb_queue_tail
(
&
packet
->
chunks
,
(
struct
sk_buff
*
)
chunk
);
__
skb_queue_tail
(
&
packet
->
chunks
,
(
struct
sk_buff
*
)
chunk
);
packet
->
size
+=
chunk_len
;
packet
->
size
+=
chunk_len
;
finish:
finish:
return
retval
;
return
retval
;
...
@@ -234,18 +232,18 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
...
@@ -234,18 +232,18 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
*
*
* The return value is a normal kernel error return value.
* The return value is a normal kernel error return value.
*/
*/
int
sctp_packet_transmit
(
s
ctp_packet_
t
*
packet
)
int
sctp_packet_transmit
(
s
truct
sctp_packe
t
*
packet
)
{
{
struct
sctp_transport
*
transport
=
packet
->
transport
;
struct
sctp_transport
*
transport
=
packet
->
transport
;
s
ctp_association_t
*
asoc
=
transport
->
asoc
;
s
truct
sctp_association
*
asoc
=
transport
->
asoc
;
struct
sctphdr
*
sh
;
struct
sctphdr
*
sh
;
__u32
crc32
;
__u32
crc32
;
struct
sk_buff
*
nskb
;
struct
sk_buff
*
nskb
;
s
ctp_chunk_t
*
chunk
;
s
truct
sctp_chunk
*
chunk
;
struct
sock
*
sk
;
struct
sock
*
sk
;
int
err
=
0
;
int
err
=
0
;
int
padding
;
/* How much padding do we need? */
int
padding
;
/* How much padding do we need? */
__u8
packet_
has_data
=
0
;
__u8
has_data
=
0
;
struct
dst_entry
*
dst
;
struct
dst_entry
*
dst
;
/* Do NOT generate a chunkless packet... */
/* Do NOT generate a chunkless packet... */
...
@@ -253,7 +251,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
...
@@ -253,7 +251,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
return
err
;
return
err
;
/* Set up convenience variables... */
/* Set up convenience variables... */
chunk
=
(
s
ctp_chunk_t
*
)
(
packet
->
chunks
.
next
);
chunk
=
(
s
truct
sctp_chunk
*
)
(
packet
->
chunks
.
next
);
sk
=
chunk
->
skb
->
sk
;
sk
=
chunk
->
skb
->
sk
;
/* Allocate the new skb. */
/* Allocate the new skb. */
...
@@ -291,8 +289,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
...
@@ -291,8 +289,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
* [This whole comment explains WORD_ROUND() below.]
* [This whole comment explains WORD_ROUND() below.]
*/
*/
SCTP_DEBUG_PRINTK
(
"***sctp_transmit_packet***
\n
"
);
SCTP_DEBUG_PRINTK
(
"***sctp_transmit_packet***
\n
"
);
while
(
NULL
!=
(
chunk
=
(
sctp_chunk_t
*
)
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
)))
{
skb_dequeue
(
&
packet
->
chunks
)))
{
chunk
->
num_times_sent
++
;
chunk
->
num_times_sent
++
;
chunk
->
sent_at
=
jiffies
;
chunk
->
sent_at
=
jiffies
;
if
(
sctp_chunk_is_data
(
chunk
))
{
if
(
sctp_chunk_is_data
(
chunk
))
{
...
@@ -309,7 +306,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
...
@@ -309,7 +306,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
chunk
->
rtt_in_progress
=
1
;
chunk
->
rtt_in_progress
=
1
;
transport
->
rto_pending
=
1
;
transport
->
rto_pending
=
1
;
}
}
packet_
has_data
=
1
;
has_data
=
1
;
}
}
memcpy
(
skb_put
(
nskb
,
chunk
->
skb
->
len
),
memcpy
(
skb_put
(
nskb
,
chunk
->
skb
->
len
),
chunk
->
skb
->
data
,
chunk
->
skb
->
len
);
chunk
->
skb
->
data
,
chunk
->
skb
->
len
);
...
@@ -399,7 +396,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
...
@@ -399,7 +396,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
asoc
->
peer
.
last_sent_to
=
transport
;
asoc
->
peer
.
last_sent_to
=
transport
;
}
}
if
(
packet_
has_data
)
{
if
(
has_data
)
{
struct
timer_list
*
timer
;
struct
timer_list
*
timer
;
unsigned
long
timeout
;
unsigned
long
timeout
;
...
@@ -456,9 +453,9 @@ int sctp_packet_transmit(sctp_packet_t *packet)
...
@@ -456,9 +453,9 @@ int sctp_packet_transmit(sctp_packet_t *packet)
/*
/*
* This private function resets the packet to a fresh state.
* This private function resets the packet to a fresh state.
*/
*/
static
void
sctp_packet_reset
(
s
ctp_packet_
t
*
packet
)
static
void
sctp_packet_reset
(
s
truct
sctp_packe
t
*
packet
)
{
{
s
ctp_chunk_t
*
chunk
=
NULL
;
s
truct
sctp_chunk
*
chunk
=
NULL
;
packet
->
size
=
SCTP_IP_OVERHEAD
;
packet
->
size
=
SCTP_IP_OVERHEAD
;
...
@@ -473,13 +470,15 @@ static void sctp_packet_reset(sctp_packet_t *packet)
...
@@ -473,13 +470,15 @@ static void sctp_packet_reset(sctp_packet_t *packet)
}
}
/* This private function handles the specifics of appending DATA chunks. */
/* This private function handles the specifics of appending DATA chunks. */
static
sctp_xmit_t
sctp_packet_append_data
(
s
ctp_packet_
t
*
packet
,
static
sctp_xmit_t
sctp_packet_append_data
(
s
truct
sctp_packe
t
*
packet
,
s
ctp_chunk_t
*
chunk
)
s
truct
sctp_chunk
*
chunk
)
{
{
sctp_xmit_t
retval
=
SCTP_XMIT_OK
;
sctp_xmit_t
retval
=
SCTP_XMIT_OK
;
size_t
datasize
,
rwnd
,
inflight
;
size_t
datasize
,
rwnd
,
inflight
;
struct
sctp_transport
*
transport
=
packet
->
transport
;
struct
sctp_transport
*
transport
=
packet
->
transport
;
__u32
max_burst_bytes
;
__u32
max_burst_bytes
;
struct
sctp_opt
*
sp
=
sctp_sk
(
transport
->
asoc
->
base
.
sk
);
struct
sctp_outq
*
q
=
&
transport
->
asoc
->
outqueue
;
/* RFC 2960 6.1 Transmission of DATA Chunks
/* RFC 2960 6.1 Transmission of DATA Chunks
*
*
...
@@ -543,11 +542,34 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet,
...
@@ -543,11 +542,34 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet,
* When a Fast Retransmit is being performed the sender SHOULD
* When a Fast Retransmit is being performed the sender SHOULD
* ignore the value of cwnd and SHOULD NOT delay retransmission.
* ignore the value of cwnd and SHOULD NOT delay retransmission.
*/
*/
if
(
!
chunk
->
fast_retransmit
)
{
if
(
!
chunk
->
fast_retransmit
)
if
(
transport
->
flight_size
>=
transport
->
cwnd
)
{
if
(
transport
->
flight_size
>=
transport
->
cwnd
)
{
retval
=
SCTP_XMIT_RWND_FULL
;
retval
=
SCTP_XMIT_RWND_FULL
;
goto
finish
;
goto
finish
;
}
}
/* Nagle's algorithm to solve small-packet problem:
* inhibit the sending of new chunks when new outgoing data arrives
* if any proeviously transmitted data on the connection remains
* unacknowledged. Unless the connection was previously idle. Check
* whether the connection is idle. No outstanding means idle, flush
* it. If outstanding bytes are less than half cwnd, the connection
* is not in the state of congestion, so also flush it.
*/
if
(
!
sp
->
nodelay
&&
q
->
outstanding_bytes
>=
transport
->
cwnd
>>
1
)
{
/* Check whether this chunk and all the rest of pending
* data will fit or whether we'll choose to delay in
* hopes of bundling a full sized packet.
*/
if
((
datasize
+
q
->
out_qlen
)
<
transport
->
asoc
->
frag_point
)
{
/* If the the chunk should be delay
* for future sending, we could not
* append it.
*/
retval
=
SCTP_XMIT_NAGLE_DELAY
;
goto
finish
;
}
}
}
/* Keep track of how many bytes are in flight over this transport. */
/* Keep track of how many bytes are in flight over this transport. */
...
...
net/sctp/outqueue.c
View file @
acbabcbe
/* SCTP kernel reference Implementation
/* SCTP kernel reference Implementation
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001
-2003
Intel Corp.
* Copyright (c) 2001-2003 International Business Machines Corp.
* Copyright (c) 2001-2003 International Business Machines Corp.
*
*
* This file is part of the SCTP kernel reference Implementation
* This file is part of the SCTP kernel reference Implementation
...
@@ -62,6 +62,33 @@ static void sctp_check_transmitted(struct sctp_outq *q,
...
@@ -62,6 +62,33 @@ static void sctp_check_transmitted(struct sctp_outq *q,
sctp_sackhdr_t
*
sack
,
sctp_sackhdr_t
*
sack
,
__u32
highest_new_tsn
);
__u32
highest_new_tsn
);
/* Add data to the front of the queue. */
static
inline
void
sctp_outq_head_data
(
struct
sctp_outq
*
q
,
struct
sctp_chunk
*
ch
)
{
__skb_queue_head
(
&
q
->
out
,
(
struct
sk_buff
*
)
ch
);
q
->
out_qlen
+=
ch
->
skb
->
len
;
return
;
}
/* Take data from the front of the queue. */
static
inline
struct
sctp_chunk
*
sctp_outq_dequeue_data
(
struct
sctp_outq
*
q
)
{
struct
sctp_chunk
*
ch
;
ch
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
q
->
out
);
if
(
ch
)
q
->
out_qlen
-=
ch
->
skb
->
len
;
return
ch
;
}
/* Add data chunk to the end of the queue. */
static
inline
void
sctp_outq_tail_data
(
struct
sctp_outq
*
q
,
struct
sctp_chunk
*
ch
)
{
__skb_queue_tail
(
&
q
->
out
,
(
struct
sk_buff
*
)
ch
);
q
->
out_qlen
+=
ch
->
skb
->
len
;
return
;
}
/* Generate a new outqueue. */
/* Generate a new outqueue. */
struct
sctp_outq
*
sctp_outq_new
(
sctp_association_t
*
asoc
)
struct
sctp_outq
*
sctp_outq_new
(
sctp_association_t
*
asoc
)
{
{
...
@@ -97,6 +124,7 @@ void sctp_outq_init(sctp_association_t *asoc, struct sctp_outq *q)
...
@@ -97,6 +124,7 @@ void sctp_outq_init(sctp_association_t *asoc, struct sctp_outq *q)
q
->
empty
=
1
;
q
->
empty
=
1
;
q
->
malloced
=
0
;
q
->
malloced
=
0
;
q
->
out_qlen
=
0
;
}
}
/* Free the outqueue structure and any related pending chunks.
/* Free the outqueue structure and any related pending chunks.
...
@@ -133,7 +161,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
...
@@ -133,7 +161,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
}
}
/* Throw away any leftover data chunks. */
/* Throw away any leftover data chunks. */
while
((
chunk
=
(
sctp_chunk_t
*
)
skb_dequeue
(
&
q
->
out
)))
while
((
chunk
=
sctp_outq_dequeue_data
(
q
)))
sctp_free_chunk
(
chunk
);
sctp_free_chunk
(
chunk
);
/* Throw away any leftover control chunks. */
/* Throw away any leftover control chunks. */
...
@@ -192,7 +220,7 @@ int sctp_outq_tail(struct sctp_outq *q, sctp_chunk_t *chunk)
...
@@ -192,7 +220,7 @@ int sctp_outq_tail(struct sctp_outq *q, sctp_chunk_t *chunk)
sctp_cname
(
SCTP_ST_CHUNK
(
chunk
->
chunk_hdr
->
type
))
sctp_cname
(
SCTP_ST_CHUNK
(
chunk
->
chunk_hdr
->
type
))
:
"Illegal Chunk"
);
:
"Illegal Chunk"
);
s
kb_queue_tail
(
&
q
->
out
,
(
struct
sk_buff
*
)
chunk
);
s
ctp_outq_tail_data
(
q
,
chunk
);
if
(
chunk
->
chunk_hdr
->
flags
&
SCTP_DATA_UNORDERED
)
if
(
chunk
->
chunk_hdr
->
flags
&
SCTP_DATA_UNORDERED
)
SCTP_INC_STATS
(
SctpOutUnorderChunks
);
SCTP_INC_STATS
(
SctpOutUnorderChunks
);
else
else
...
@@ -201,7 +229,7 @@ int sctp_outq_tail(struct sctp_outq *q, sctp_chunk_t *chunk)
...
@@ -201,7 +229,7 @@ int sctp_outq_tail(struct sctp_outq *q, sctp_chunk_t *chunk)
break
;
break
;
};
};
}
else
{
}
else
{
skb_queue_tail
(
&
q
->
control
,
(
struct
sk_buff
*
)
chunk
);
__
skb_queue_tail
(
&
q
->
control
,
(
struct
sk_buff
*
)
chunk
);
SCTP_INC_STATS
(
SctpOutCtrlChunks
);
SCTP_INC_STATS
(
SctpOutCtrlChunks
);
}
}
...
@@ -351,7 +379,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
...
@@ -351,7 +379,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
*
*
* The return value is a normal kernel error return value.
* The return value is a normal kernel error return value.
*/
*/
static
int
sctp_outq_flush_rtx
(
struct
sctp_outq
*
q
,
s
ctp_packet_
t
*
pkt
,
static
int
sctp_outq_flush_rtx
(
struct
sctp_outq
*
q
,
s
truct
sctp_packe
t
*
pkt
,
int
rtx_timeout
,
int
*
start_timer
)
int
rtx_timeout
,
int
*
start_timer
)
{
{
struct
list_head
*
lqueue
;
struct
list_head
*
lqueue
;
...
@@ -385,17 +413,6 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, sctp_packet_t *pkt,
...
@@ -385,17 +413,6 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, sctp_packet_t *pkt,
while
(
lchunk
)
{
while
(
lchunk
)
{
chunk
=
list_entry
(
lchunk
,
sctp_chunk_t
,
transmitted_list
);
chunk
=
list_entry
(
lchunk
,
sctp_chunk_t
,
transmitted_list
);
#if 0
/* If a chunk has been tried for more than SCTP_DEF_MAX_SEND
* times, discard it, and check the empty flag of the outqueue.
*
* --xguo
*/
if (chunk->snd_count > SCTP_DEF_MAX_SEND) {
sctp_free_chunk(chunk);
continue;
}
#endif
/* 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
...
@@ -462,7 +479,7 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, sctp_packet_t *pkt,
...
@@ -462,7 +479,7 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, sctp_packet_t *pkt,
* chunk that is currently in the process of fragmentation.
* chunk that is currently in the process of fragmentation.
*/
*/
void
sctp_xmit_frag
(
struct
sctp_outq
*
q
,
struct
sk_buff
*
pos
,
void
sctp_xmit_frag
(
struct
sctp_outq
*
q
,
struct
sk_buff
*
pos
,
s
ctp_packet_
t
*
packet
,
sctp_chunk_t
*
frag
,
__u32
tsn
)
s
truct
sctp_packe
t
*
packet
,
sctp_chunk_t
*
frag
,
__u32
tsn
)
{
{
struct
sctp_transport
*
transport
=
packet
->
transport
;
struct
sctp_transport
*
transport
=
packet
->
transport
;
struct
sk_buff_head
*
queue
=
&
q
->
out
;
struct
sk_buff_head
*
queue
=
&
q
->
out
;
...
@@ -480,11 +497,11 @@ void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos,
...
@@ -480,11 +497,11 @@ void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos,
SCTP_DEBUG_PRINTK
(
"sctp_xmit_frag: q not empty. "
SCTP_DEBUG_PRINTK
(
"sctp_xmit_frag: q not empty. "
"adding 0x%x to outqueue
\n
"
,
"adding 0x%x to outqueue
\n
"
,
ntohl
(
frag
->
subh
.
data_hdr
->
tsn
));
ntohl
(
frag
->
subh
.
data_hdr
->
tsn
));
if
(
pos
)
{
if
(
pos
)
skb_insert
(
pos
,
(
struct
sk_buff
*
)
frag
);
__skb_insert
((
struct
sk_buff
*
)
frag
,
pos
->
prev
,
}
else
{
pos
,
pos
->
list
);
skb_queue_tail
(
queue
,
(
struct
sk_buff
*
)
frag
);
else
}
__skb_queue_tail
(
queue
,
(
struct
sk_buff
*
)
frag
);
return
;
return
;
}
}
...
@@ -496,11 +513,11 @@ void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos,
...
@@ -496,11 +513,11 @@ void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos,
SCTP_DEBUG_PRINTK
(
"sctp_xmit_frag: rwnd full. "
SCTP_DEBUG_PRINTK
(
"sctp_xmit_frag: rwnd full. "
"adding 0x%x to outqueue
\n
"
,
"adding 0x%x to outqueue
\n
"
,
ntohl
(
frag
->
subh
.
data_hdr
->
tsn
));
ntohl
(
frag
->
subh
.
data_hdr
->
tsn
));
if
(
pos
)
{
if
(
pos
)
skb_insert
(
pos
,
(
struct
sk_buff
*
)
frag
);
__skb_insert
((
struct
sk_buff
*
)
frag
,
pos
->
prev
,
}
else
{
pos
,
pos
->
list
);
skb_queue_tail
(
queue
,
(
struct
sk_buff
*
)
frag
);
else
}
__skb_queue_tail
(
queue
,
(
struct
sk_buff
*
)
frag
);
break
;
break
;
case
SCTP_XMIT_OK
:
case
SCTP_XMIT_OK
:
...
@@ -512,11 +529,11 @@ void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos,
...
@@ -512,11 +529,11 @@ void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos,
SCTP_DEBUG_PRINTK
(
"sctp_xmit_frag: force output "
SCTP_DEBUG_PRINTK
(
"sctp_xmit_frag: force output "
"failed. adding 0x%x to outqueue
\n
"
,
"failed. adding 0x%x to outqueue
\n
"
,
ntohl
(
frag
->
subh
.
data_hdr
->
tsn
));
ntohl
(
frag
->
subh
.
data_hdr
->
tsn
));
if
(
pos
)
{
if
(
pos
)
skb_insert
(
pos
,
(
struct
sk_buff
*
)
frag
);
__skb_insert
((
struct
sk_buff
*
)
frag
,
pos
->
prev
,
}
else
{
pos
,
pos
->
list
);
skb_queue_tail
(
queue
,
(
struct
sk_buff
*
)
frag
);
else
}
__skb_queue_tail
(
queue
,(
struct
sk_buff
*
)
frag
);
}
else
{
}
else
{
SCTP_DEBUG_PRINTK
(
"sctp_xmit_frag: force output "
SCTP_DEBUG_PRINTK
(
"sctp_xmit_frag: force output "
"success. 0x%x sent
\n
"
,
"success. 0x%x sent
\n
"
,
...
@@ -537,7 +554,7 @@ void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos,
...
@@ -537,7 +554,7 @@ void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos,
* The argument 'frag' point to the first fragment and it holds the list
* The argument 'frag' point to the first fragment and it holds the list
* 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
,
s
ctp_packet_t
*
packe
t
,
void
sctp_xmit_fragmented_chunks
(
struct
sctp_outq
*
q
,
s
truct
sctp_packet
*
pk
t
,
sctp_chunk_t
*
frag
)
sctp_chunk_t
*
frag
)
{
{
sctp_association_t
*
asoc
=
frag
->
asoc
;
sctp_association_t
*
asoc
=
frag
->
asoc
;
...
@@ -557,13 +574,13 @@ void sctp_xmit_fragmented_chunks(struct sctp_outq *q, sctp_packet_t *packet,
...
@@ -557,13 +574,13 @@ void sctp_xmit_fragmented_chunks(struct sctp_outq *q, sctp_packet_t *packet,
pos
=
skb_peek
(
&
q
->
out
);
pos
=
skb_peek
(
&
q
->
out
);
/* Transmit the first fragment. */
/* Transmit the first fragment. */
sctp_xmit_frag
(
q
,
pos
,
p
acke
t
,
frag
,
tsn
++
);
sctp_xmit_frag
(
q
,
pos
,
p
k
t
,
frag
,
tsn
++
);
/* 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
,
sctp_chunk_t
,
frag_list
);
frag
=
list_entry
(
lfrag
,
sctp_chunk_t
,
frag_list
);
sctp_xmit_frag
(
q
,
pos
,
p
acke
t
,
frag
,
tsn
++
);
sctp_xmit_frag
(
q
,
pos
,
p
k
t
,
frag
,
tsn
++
);
}
}
}
}
...
@@ -672,15 +689,14 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
...
@@ -672,15 +689,14 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk,
*
*
* Description: Send everything in q which we legally can, subject to
* Description: Send everything in q which we legally can, subject to
* congestion limitations.
* congestion limitations.
*
* * Note: This function can be called from multiple contexts so appropriate
* Note: This function can be called from multiple contexts so appropriate
* locking concerns must be made. Today we use the sock lock to protect
* locking concerns must be made. Today we use the sock lock to protect
* this function.
* this function.
*/
*/
int
sctp_outq_flush
(
struct
sctp_outq
*
q
,
int
rtx_timeout
)
int
sctp_outq_flush
(
struct
sctp_outq
*
q
,
int
rtx_timeout
)
{
{
s
ctp_packet_
t
*
packet
;
s
truct
sctp_packe
t
*
packet
;
s
ctp_packet_
t
singleton
;
s
truct
sctp_packe
t
singleton
;
sctp_association_t
*
asoc
=
q
->
asoc
;
sctp_association_t
*
asoc
=
q
->
asoc
;
int
ecn_capable
=
asoc
->
peer
.
ecn_capable
;
int
ecn_capable
=
asoc
->
peer
.
ecn_capable
;
__u16
sport
=
asoc
->
base
.
bind_addr
.
port
;
__u16
sport
=
asoc
->
base
.
bind_addr
.
port
;
...
@@ -852,7 +868,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -852,7 +868,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
/* Finally, transmit new packets. */
/* Finally, transmit new packets. */
start_timer
=
0
;
start_timer
=
0
;
queue
=
&
q
->
out
;
queue
=
&
q
->
out
;
while
(
NULL
!=
(
chunk
=
(
sctp_chunk_t
*
)
skb_dequeue
(
queue
)))
{
while
(
NULL
!=
(
chunk
=
sctp_outq_dequeue_data
(
q
)))
{
/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
* stream identifier.
* stream identifier.
*/
*/
...
@@ -925,6 +942,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -925,6 +942,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
switch
(
status
)
{
switch
(
status
)
{
case
SCTP_XMIT_PMTU_FULL
:
case
SCTP_XMIT_PMTU_FULL
:
case
SCTP_XMIT_RWND_FULL
:
case
SCTP_XMIT_RWND_FULL
:
case
SCTP_XMIT_NAGLE_DELAY
:
/* We could not append this chunk, so put
/* We could not append this chunk, so put
* the chunk back on the output queue.
* the chunk back on the output queue.
*/
*/
...
@@ -932,7 +950,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -932,7 +950,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
"not transmit TSN: 0x%x, status: %d
\n
"
,
"not transmit TSN: 0x%x, status: %d
\n
"
,
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
status
);
status
);
s
kb_queue_head
(
queue
,
(
struct
sk_buff
*
)
chunk
);
s
ctp_outq_head_data
(
q
,
chunk
);
goto
sctp_flush_out
;
goto
sctp_flush_out
;
break
;
break
;
...
@@ -994,6 +1012,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -994,6 +1012,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
}
}
sctp_flush_out:
sctp_flush_out:
/* Before returning, examine all the transports touched in
/* Before returning, examine all the transports touched in
* this call. Right now, we bluntly force clear all the
* this call. Right now, we bluntly force clear all the
* transports. Things might change after we implement Nagle.
* transports. Things might change after we implement Nagle.
...
@@ -1163,11 +1182,10 @@ int sctp_outq_sack(struct sctp_outq *q, sctp_sackhdr_t *sack)
...
@@ -1163,11 +1182,10 @@ int sctp_outq_sack(struct sctp_outq *q, sctp_sackhdr_t *sack)
sack_a_rwnd
=
ntohl
(
sack
->
a_rwnd
);
sack_a_rwnd
=
ntohl
(
sack
->
a_rwnd
);
outstanding
=
q
->
outstanding_bytes
;
outstanding
=
q
->
outstanding_bytes
;
if
(
outstanding
<
sack_a_rwnd
)
{
if
(
outstanding
<
sack_a_rwnd
)
sack_a_rwnd
-=
outstanding
;
sack_a_rwnd
-=
outstanding
;
}
else
{
else
sack_a_rwnd
=
0
;
sack_a_rwnd
=
0
;
}
asoc
->
peer
.
rwnd
=
sack_a_rwnd
;
asoc
->
peer
.
rwnd
=
sack_a_rwnd
;
...
...
net/sctp/protocol.c
View file @
acbabcbe
...
@@ -557,10 +557,13 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long event,
...
@@ -557,10 +557,13 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long event,
*/
*/
int
sctp_ctl_sock_init
(
void
)
int
sctp_ctl_sock_init
(
void
)
{
{
int
err
=
0
;
int
err
;
int
family
=
PF_INET
;
sa_family_t
family
;
SCTP_V6
(
family
=
PF_INET6
;)
if
(
sctp_get_pf_specific
(
PF_INET6
))
family
=
PF_INET6
;
else
family
=
PF_INET
;
err
=
sock_create
(
family
,
SOCK_SEQPACKET
,
IPPROTO_SCTP
,
err
=
sock_create
(
family
,
SOCK_SEQPACKET
,
IPPROTO_SCTP
,
&
sctp_ctl_socket
);
&
sctp_ctl_socket
);
...
...
net/sctp/sm_sideeffect.c
View file @
acbabcbe
...
@@ -256,7 +256,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
...
@@ -256,7 +256,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
sctp_cmd_t
*
cmd
;
sctp_cmd_t
*
cmd
;
sctp_chunk_t
*
new_obj
;
sctp_chunk_t
*
new_obj
;
sctp_chunk_t
*
chunk
=
NULL
;
sctp_chunk_t
*
chunk
=
NULL
;
s
ctp_packet_
t
*
packet
;
s
truct
sctp_packe
t
*
packet
;
struct
list_head
*
pos
;
struct
list_head
*
pos
;
struct
timer_list
*
timer
;
struct
timer_list
*
timer
;
unsigned
long
timeout
;
unsigned
long
timeout
;
...
...
net/sctp/sm_statefuns.c
View file @
acbabcbe
...
@@ -189,7 +189,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep,
...
@@ -189,7 +189,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep,
sctp_chunk_t
*
repl
;
sctp_chunk_t
*
repl
;
sctp_association_t
*
new_asoc
;
sctp_association_t
*
new_asoc
;
sctp_chunk_t
*
err_chunk
;
sctp_chunk_t
*
err_chunk
;
s
ctp_packet_
t
*
packet
;
s
truct
sctp_packe
t
*
packet
;
sctp_unrecognized_param_t
*
unk_param
;
sctp_unrecognized_param_t
*
unk_param
;
int
len
;
int
len
;
...
@@ -354,10 +354,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep,
...
@@ -354,10 +354,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep,
sctp_init_chunk_t
*
initchunk
;
sctp_init_chunk_t
*
initchunk
;
__u32
init_tag
;
__u32
init_tag
;
sctp_chunk_t
*
err_chunk
;
sctp_chunk_t
*
err_chunk
;
s
ctp_packet_
t
*
packet
;
s
truct
sctp_packe
t
*
packet
;
sctp_disposition_t
ret
;
sctp_disposition_t
ret
;
/* 6.10 Bundling
/* 6.10 Bundling
* An endpoint MUST NOT bundle INIT, INIT ACK or
* An endpoint MUST NOT bundle INIT, INIT ACK or
* SHUTDOWN COMPLETE with any other chunks.
* SHUTDOWN COMPLETE with any other chunks.
...
@@ -912,14 +911,14 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
...
@@ -912,14 +911,14 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
int
len
;
int
len
;
s
ctp_packet_
t
*
pkt
;
s
truct
sctp_packe
t
*
pkt
;
sctp_addr_param_t
*
addrparm
;
sctp_addr_param_t
*
addrparm
;
sctp_errhdr_t
*
errhdr
;
sctp_errhdr_t
*
errhdr
;
sctp_endpoint_t
*
ep
;
sctp_endpoint_t
*
ep
;
char
buffer
[
sizeof
(
sctp_errhdr_t
)
+
sizeof
(
sctp_addr_param_t
)];
char
buffer
[
sizeof
(
sctp_errhdr_t
)
+
sizeof
(
sctp_addr_param_t
)];
/* Build the error on the stack. We are way to malloc
/* Build the error on the stack. We are way to malloc
crazy
*
malloc crazy
throughout the code today.
* throughout the code today.
*/
*/
errhdr
=
(
sctp_errhdr_t
*
)
buffer
;
errhdr
=
(
sctp_errhdr_t
*
)
buffer
;
addrparm
=
(
sctp_addr_param_t
*
)
errhdr
->
variable
;
addrparm
=
(
sctp_addr_param_t
*
)
errhdr
->
variable
;
...
@@ -1105,11 +1104,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
...
@@ -1105,11 +1104,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
sctp_chunk_t
*
repl
;
sctp_chunk_t
*
repl
;
sctp_association_t
*
new_asoc
;
sctp_association_t
*
new_asoc
;
sctp_chunk_t
*
err_chunk
;
sctp_chunk_t
*
err_chunk
;
s
ctp_packet_
t
*
packet
;
s
truct
sctp_packe
t
*
packet
;
sctp_unrecognized_param_t
*
unk_param
;
sctp_unrecognized_param_t
*
unk_param
;
int
len
;
int
len
;
/* 6.10 Bundling
/* 6.10 Bundling
* An endpoint MUST NOT bundle INIT, INIT ACK or
* An endpoint MUST NOT bundle INIT, INIT ACK or
* SHUTDOWN COMPLETE with any other chunks.
* SHUTDOWN COMPLETE with any other chunks.
...
@@ -2751,7 +2749,7 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const sctp_endpoint_t *ep,
...
@@ -2751,7 +2749,7 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const sctp_endpoint_t *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_packet_
t
*
packet
=
NULL
;
s
truct
sctp_packe
t
*
packet
=
NULL
;
sctp_chunk_t
*
chunk
=
arg
;
sctp_chunk_t
*
chunk
=
arg
;
sctp_chunk_t
*
abort
;
sctp_chunk_t
*
abort
;
...
@@ -2953,7 +2951,7 @@ sctp_disposition_t sctp_sf_shut_8_4_5(const sctp_endpoint_t *ep,
...
@@ -2953,7 +2951,7 @@ sctp_disposition_t sctp_sf_shut_8_4_5(const sctp_endpoint_t *ep,
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
s
ctp_packet_
t
*
packet
=
NULL
;
s
truct
sctp_packe
t
*
packet
=
NULL
;
sctp_chunk_t
*
chunk
=
arg
;
sctp_chunk_t
*
chunk
=
arg
;
sctp_chunk_t
*
shut
;
sctp_chunk_t
*
shut
;
...
@@ -4377,13 +4375,13 @@ sctp_sackhdr_t *sctp_sm_pull_sack(sctp_chunk_t *chunk)
...
@@ -4377,13 +4375,13 @@ sctp_sackhdr_t *sctp_sm_pull_sack(sctp_chunk_t *chunk)
/* Create an ABORT packet to be sent as a response, with the specified
/* Create an ABORT packet to be sent as a response, with the specified
* error causes.
* error causes.
*/
*/
s
ctp_packet_
t
*
sctp_abort_pkt_new
(
const
sctp_endpoint_t
*
ep
,
s
truct
sctp_packe
t
*
sctp_abort_pkt_new
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_association_t
*
asoc
,
sctp_chunk_t
*
chunk
,
sctp_chunk_t
*
chunk
,
const
void
*
payload
,
const
void
*
payload
,
size_t
paylen
)
size_t
paylen
)
{
{
s
ctp_packet_
t
*
packet
;
s
truct
sctp_packe
t
*
packet
;
sctp_chunk_t
*
abort
;
sctp_chunk_t
*
abort
;
packet
=
sctp_ootb_pkt_new
(
asoc
,
chunk
);
packet
=
sctp_ootb_pkt_new
(
asoc
,
chunk
);
...
@@ -4413,10 +4411,10 @@ sctp_packet_t *sctp_abort_pkt_new(const sctp_endpoint_t *ep,
...
@@ -4413,10 +4411,10 @@ sctp_packet_t *sctp_abort_pkt_new(const sctp_endpoint_t *ep,
}
}
/* Allocate a packet for responding in the OOTB conditions. */
/* Allocate a packet for responding in the OOTB conditions. */
s
ctp_packet_
t
*
sctp_ootb_pkt_new
(
const
sctp_association_t
*
asoc
,
s
truct
sctp_packe
t
*
sctp_ootb_pkt_new
(
const
sctp_association_t
*
asoc
,
const
sctp_chunk_t
*
chunk
)
const
sctp_chunk_t
*
chunk
)
{
{
s
ctp_packet_
t
*
packet
;
s
truct
sctp_packe
t
*
packet
;
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
__u16
sport
;
__u16
sport
;
__u16
dport
;
__u16
dport
;
...
@@ -4449,7 +4447,7 @@ sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
...
@@ -4449,7 +4447,7 @@ sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
goto
nomem
;
goto
nomem
;
/* Allocate a new packet for sending the response. */
/* Allocate a new packet for sending the response. */
packet
=
t_new
(
s
ctp_packet_
t
,
GFP_ATOMIC
);
packet
=
t_new
(
s
truct
sctp_packe
t
,
GFP_ATOMIC
);
if
(
!
packet
)
if
(
!
packet
)
goto
nomem_packet
;
goto
nomem_packet
;
...
@@ -4471,7 +4469,7 @@ sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
...
@@ -4471,7 +4469,7 @@ sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
}
}
/* Free the packet allocated earlier for responding in the OOTB condition. */
/* Free the packet allocated earlier for responding in the OOTB condition. */
void
sctp_ootb_pkt_free
(
s
ctp_packet_
t
*
packet
)
void
sctp_ootb_pkt_free
(
s
truct
sctp_packe
t
*
packet
)
{
{
sctp_transport_free
(
packet
->
transport
);
sctp_transport_free
(
packet
->
transport
);
sctp_packet_free
(
packet
);
sctp_packet_free
(
packet
);
...
@@ -4484,7 +4482,7 @@ void sctp_send_stale_cookie_err(const sctp_endpoint_t *ep,
...
@@ -4484,7 +4482,7 @@ void sctp_send_stale_cookie_err(const sctp_endpoint_t *ep,
sctp_cmd_seq_t
*
commands
,
sctp_cmd_seq_t
*
commands
,
sctp_chunk_t
*
err_chunk
)
sctp_chunk_t
*
err_chunk
)
{
{
s
ctp_packet_
t
*
packet
;
s
truct
sctp_packe
t
*
packet
;
if
(
err_chunk
)
{
if
(
err_chunk
)
{
packet
=
sctp_ootb_pkt_new
(
asoc
,
chunk
);
packet
=
sctp_ootb_pkt_new
(
asoc
,
chunk
);
...
...
net/sctp/socket.c
View file @
acbabcbe
...
@@ -1231,7 +1231,7 @@ SCTP_STATIC int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr
...
@@ -1231,7 +1231,7 @@ SCTP_STATIC int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr
return
err
;
return
err
;
}
}
static
in
line
in
t
sctp_setsockopt_disable_fragments
(
struct
sock
*
sk
,
static
int
sctp_setsockopt_disable_fragments
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
char
*
optval
,
int
optlen
)
{
{
int
val
;
int
val
;
...
@@ -1247,7 +1247,7 @@ static inline int sctp_setsockopt_disable_fragments(struct sock *sk,
...
@@ -1247,7 +1247,7 @@ static inline int sctp_setsockopt_disable_fragments(struct sock *sk,
return
0
;
return
0
;
}
}
static
in
line
in
t
sctp_setsockopt_events
(
struct
sock
*
sk
,
char
*
optval
,
static
int
sctp_setsockopt_events
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
int
optlen
)
{
{
if
(
optlen
!=
sizeof
(
struct
sctp_event_subscribe
))
if
(
optlen
!=
sizeof
(
struct
sctp_event_subscribe
))
...
@@ -1257,7 +1257,7 @@ static inline int sctp_setsockopt_events(struct sock *sk, char *optval,
...
@@ -1257,7 +1257,7 @@ static inline int sctp_setsockopt_events(struct sock *sk, char *optval,
return
0
;
return
0
;
}
}
static
in
line
in
t
sctp_setsockopt_autoclose
(
struct
sock
*
sk
,
char
*
optval
,
static
int
sctp_setsockopt_autoclose
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
int
optlen
)
{
{
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
...
@@ -1274,7 +1274,7 @@ static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
...
@@ -1274,7 +1274,7 @@ static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
return
0
;
return
0
;
}
}
static
in
line
in
t
sctp_setsockopt_peer_addr_params
(
struct
sock
*
sk
,
static
int
sctp_setsockopt_peer_addr_params
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
char
*
optval
,
int
optlen
)
{
{
struct
sctp_paddrparams
params
;
struct
sctp_paddrparams
params
;
...
@@ -1333,7 +1333,7 @@ static inline int sctp_setsockopt_peer_addr_params(struct sock *sk,
...
@@ -1333,7 +1333,7 @@ static inline int sctp_setsockopt_peer_addr_params(struct sock *sk,
return
0
;
return
0
;
}
}
static
in
line
in
t
sctp_setsockopt_initmsg
(
struct
sock
*
sk
,
char
*
optval
,
static
int
sctp_setsockopt_initmsg
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
int
optlen
)
{
{
if
(
optlen
!=
sizeof
(
struct
sctp_initmsg
))
if
(
optlen
!=
sizeof
(
struct
sctp_initmsg
))
...
@@ -1358,7 +1358,7 @@ static inline int sctp_setsockopt_initmsg(struct sock *sk, char *optval,
...
@@ -1358,7 +1358,7 @@ static inline int sctp_setsockopt_initmsg(struct sock *sk, char *optval,
* sinfo_timetolive. The user must provide the sinfo_assoc_id field in
* sinfo_timetolive. The user must provide the sinfo_assoc_id field in
* to this call if the caller is using the UDP model.
* to this call if the caller is using the UDP model.
*/
*/
static
in
line
in
t
sctp_setsockopt_default_send_param
(
struct
sock
*
sk
,
static
int
sctp_setsockopt_default_send_param
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
char
*
optval
,
int
optlen
)
{
{
struct
sctp_sndrcvinfo
info
;
struct
sctp_sndrcvinfo
info
;
...
@@ -1416,6 +1416,31 @@ static int sctp_setsockopt_peer_prim(struct sock *sk, char *optval, int optlen)
...
@@ -1416,6 +1416,31 @@ static int sctp_setsockopt_peer_prim(struct sock *sk, char *optval, int optlen)
return
0
;
return
0
;
}
}
/*
*
* 7.1.5 SCTP_NODELAY
*
* Turn on/off any Nagle-like algorithm. This means that packets are
* generally sent as soon as possible and no unnecessary delays are
* introduced, at the cost of more packets in the network. Expects an
* integer boolean flag.
*/
static
int
sctp_setsockopt_nodelay
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
{
__u8
val
;
if
(
optlen
<
sizeof
(
__u8
))
return
-
EINVAL
;
if
(
get_user
(
val
,
(
__u8
*
)
optval
))
return
-
EFAULT
;
sctp_sk
(
sk
)
->
nodelay
=
(
val
==
0
)
?
0
:
1
;
return
0
;
}
/* API 6.2 setsockopt(), getsockopt()
/* API 6.2 setsockopt(), getsockopt()
*
*
* Applications use setsockopt() and getsockopt() to set or retrieve
* Applications use setsockopt() and getsockopt() to set or retrieve
...
@@ -1515,6 +1540,10 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
...
@@ -1515,6 +1540,10 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
retval
=
sctp_setsockopt_peer_prim
(
sk
,
optval
,
optlen
);
retval
=
sctp_setsockopt_peer_prim
(
sk
,
optval
,
optlen
);
break
;
break
;
case
SCTP_NODELAY
:
retval
=
sctp_setsockopt_nodelay
(
sk
,
optval
,
optlen
);
break
;
default:
default:
retval
=
-
ENOPROTOOPT
;
retval
=
-
ENOPROTOOPT
;
break
;
break
;
...
@@ -1786,7 +1815,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
...
@@ -1786,7 +1815,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
sp
->
disable_fragments
=
0
;
sp
->
disable_fragments
=
0
;
/* Turn on/off any Nagle-like algorithm. */
/* Turn on/off any Nagle-like algorithm. */
sp
->
nodelay
=
0
;
sp
->
nodelay
=
1
;
/* Auto-close idle associations after the configured
/* Auto-close idle associations after the configured
* number of seconds. A value of 0 disables this
* number of seconds. A value of 0 disables this
...
@@ -1905,7 +1934,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, char *optval,
...
@@ -1905,7 +1934,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, char *optval,
return
(
retval
);
return
(
retval
);
}
}
static
in
line
in
t
sctp_getsockopt_disable_fragments
(
struct
sock
*
sk
,
int
len
,
static
int
sctp_getsockopt_disable_fragments
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
char
*
optval
,
int
*
optlen
)
{
{
int
val
;
int
val
;
...
@@ -1922,7 +1951,7 @@ static inline int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
...
@@ -1922,7 +1951,7 @@ static inline int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
return
0
;
return
0
;
}
}
static
in
line
in
t
sctp_getsockopt_set_events
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
static
int
sctp_getsockopt_set_events
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
{
{
if
(
len
!=
sizeof
(
struct
sctp_event_subscribe
))
if
(
len
!=
sizeof
(
struct
sctp_event_subscribe
))
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -1931,7 +1960,7 @@ static inline int sctp_getsockopt_set_events(struct sock *sk, int len, char *opt
...
@@ -1931,7 +1960,7 @@ static inline int sctp_getsockopt_set_events(struct sock *sk, int len, char *opt
return
0
;
return
0
;
}
}
static
in
line
in
t
sctp_getsockopt_autoclose
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
static
int
sctp_getsockopt_autoclose
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
{
{
/* Applicable to UDP-style socket only */
/* Applicable to UDP-style socket only */
if
(
SCTP_SOCKET_TCP
==
sctp_sk
(
sk
)
->
type
)
if
(
SCTP_SOCKET_TCP
==
sctp_sk
(
sk
)
->
type
)
...
@@ -1975,7 +2004,7 @@ SCTP_STATIC int sctp_do_peeloff(sctp_association_t *assoc, struct socket **newso
...
@@ -1975,7 +2004,7 @@ SCTP_STATIC int sctp_do_peeloff(sctp_association_t *assoc, struct socket **newso
return
err
;
return
err
;
}
}
static
in
line
in
t
sctp_getsockopt_peeloff
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
static
int
sctp_getsockopt_peeloff
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
{
{
sctp_peeloff_arg_t
peeloff
;
sctp_peeloff_arg_t
peeloff
;
struct
socket
*
newsock
;
struct
socket
*
newsock
;
...
@@ -2018,7 +2047,7 @@ static inline int sctp_getsockopt_peeloff(struct sock *sk, int len, char *optval
...
@@ -2018,7 +2047,7 @@ static inline int sctp_getsockopt_peeloff(struct sock *sk, int len, char *optval
return
retval
;
return
retval
;
}
}
static
in
line
in
t
sctp_getsockopt_peer_addr_params
(
struct
sock
*
sk
,
int
len
,
static
int
sctp_getsockopt_peer_addr_params
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
char
*
optval
,
int
*
optlen
)
{
{
struct
sctp_paddrparams
params
;
struct
sctp_paddrparams
params
;
...
@@ -2062,7 +2091,7 @@ static inline int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
...
@@ -2062,7 +2091,7 @@ static inline int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
return
0
;
return
0
;
}
}
static
in
line
in
t
sctp_getsockopt_initmsg
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
static
int
sctp_getsockopt_initmsg
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
{
{
if
(
len
!=
sizeof
(
struct
sctp_initmsg
))
if
(
len
!=
sizeof
(
struct
sctp_initmsg
))
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -2141,7 +2170,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
...
@@ -2141,7 +2170,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
return
0
;
return
0
;
}
}
static
in
line
in
t
sctp_getsockopt_local_addrs_num
(
struct
sock
*
sk
,
int
len
,
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
;
...
@@ -2180,7 +2209,7 @@ static inline int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
...
@@ -2180,7 +2209,7 @@ static inline int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
return
0
;
return
0
;
}
}
static
in
line
in
t
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
)
{
{
sctp_bind_addr_t
*
bp
;
sctp_bind_addr_t
*
bp
;
...
@@ -2282,7 +2311,7 @@ static int sctp_getsockopt_peer_prim(struct sock *sk, int len,
...
@@ -2282,7 +2311,7 @@ static int sctp_getsockopt_peer_prim(struct sock *sk, int len,
*
*
* For getsockopt, it get the default sctp_sndrcvinfo structure.
* For getsockopt, it get the default sctp_sndrcvinfo structure.
*/
*/
static
in
line
in
t
sctp_getsockopt_default_send_param
(
struct
sock
*
sk
,
static
int
sctp_getsockopt_default_send_param
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
int
len
,
char
*
optval
,
int
*
optlen
)
{
{
struct
sctp_sndrcvinfo
info
;
struct
sctp_sndrcvinfo
info
;
...
@@ -2309,6 +2338,33 @@ static inline int sctp_getsockopt_default_send_param(struct sock *sk,
...
@@ -2309,6 +2338,33 @@ static inline int sctp_getsockopt_default_send_param(struct sock *sk,
return
0
;
return
0
;
}
}
/*
*
* 7.1.5 SCTP_NODELAY
*
* Turn on/off any Nagle-like algorithm. This means that packets are
* generally sent as soon as possible and no unnecessary delays are
* introduced, at the cost of more packets in the network. Expects an
* integer boolean flag.
*/
static
int
sctp_getsockopt_nodelay
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
{
__u8
val
;
if
(
len
<
sizeof
(
__u8
))
return
-
EINVAL
;
len
=
sizeof
(
__u8
);
val
=
(
sctp_sk
(
sk
)
->
nodelay
==
1
);
if
(
put_user
(
len
,
optlen
))
return
-
EFAULT
;
if
(
copy_to_user
(
optval
,
&
val
,
len
))
return
-
EFAULT
;
return
0
;
}
SCTP_STATIC
int
sctp_getsockopt
(
struct
sock
*
sk
,
int
level
,
int
optname
,
SCTP_STATIC
int
sctp_getsockopt
(
struct
sock
*
sk
,
int
level
,
int
optname
,
char
*
optval
,
int
*
optlen
)
char
*
optval
,
int
*
optlen
)
{
{
...
@@ -2382,6 +2438,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
...
@@ -2382,6 +2438,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
case
SCTP_SET_PEER_PRIMARY_ADDR
:
case
SCTP_SET_PEER_PRIMARY_ADDR
:
retval
=
sctp_getsockopt_peer_prim
(
sk
,
len
,
optval
,
optlen
);
retval
=
sctp_getsockopt_peer_prim
(
sk
,
len
,
optval
,
optlen
);
break
;
break
;
case
SCTP_NODELAY
:
retval
=
sctp_getsockopt_nodelay
(
sk
,
len
,
optval
,
optlen
);
break
;
default:
default:
retval
=
-
ENOPROTOOPT
;
retval
=
-
ENOPROTOOPT
;
break
;
break
;
...
@@ -2689,7 +2748,6 @@ int sctp_inet_listen(struct socket *sock, int backlog)
...
@@ -2689,7 +2748,6 @@ int sctp_inet_listen(struct socket *sock, int backlog)
case
SOCK_SEQPACKET
:
case
SOCK_SEQPACKET
:
err
=
sctp_seqpacket_listen
(
sk
,
backlog
);
err
=
sctp_seqpacket_listen
(
sk
,
backlog
);
break
;
break
;
case
SOCK_STREAM
:
case
SOCK_STREAM
:
err
=
sctp_stream_listen
(
sk
,
backlog
);
err
=
sctp_stream_listen
(
sk
,
backlog
);
break
;
break
;
...
@@ -3077,7 +3135,8 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, int no
...
@@ -3077,7 +3135,8 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, int no
}
}
/* Verify that this is a valid address. */
/* Verify that this is a valid address. */
static
int
sctp_verify_addr
(
struct
sock
*
sk
,
union
sctp_addr
*
addr
,
int
len
)
static
inline
int
sctp_verify_addr
(
struct
sock
*
sk
,
union
sctp_addr
*
addr
,
int
len
)
{
{
struct
sctp_af
*
af
;
struct
sctp_af
*
af
;
...
...
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