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
5656b6ca
Commit
5656b6ca
authored
Nov 29, 2009
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'net-next' of
git://git.kernel.org/pub/scm/linux/kernel/git/vxy/lksctp-dev
parents
c1ac403b
4814326b
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
224 additions
and
500 deletions
+224
-500
Documentation/feature-removal-schedule.txt
Documentation/feature-removal-schedule.txt
+0
-12
include/linux/sctp.h
include/linux/sctp.h
+1
-0
include/net/sctp/constants.h
include/net/sctp/constants.h
+4
-0
include/net/sctp/sm.h
include/net/sctp/sm.h
+2
-1
include/net/sctp/structs.h
include/net/sctp/structs.h
+10
-6
include/net/sctp/user.h
include/net/sctp/user.h
+44
-90
net/sctp/associola.c
net/sctp/associola.c
+23
-4
net/sctp/chunk.c
net/sctp/chunk.c
+14
-1
net/sctp/output.c
net/sctp/output.c
+13
-37
net/sctp/outqueue.c
net/sctp/outqueue.c
+22
-0
net/sctp/protocol.c
net/sctp/protocol.c
+3
-0
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+9
-4
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+3
-2
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+17
-9
net/sctp/socket.c
net/sctp/socket.c
+6
-329
net/sctp/sysctl.c
net/sctp/sysctl.c
+13
-0
net/sctp/transport.c
net/sctp/transport.c
+40
-5
No files found.
Documentation/feature-removal-schedule.txt
View file @
5656b6ca
...
@@ -302,18 +302,6 @@ Who: ocfs2-devel@oss.oracle.com
...
@@ -302,18 +302,6 @@ Who: ocfs2-devel@oss.oracle.com
---------------------------
---------------------------
What: SCTP_GET_PEER_ADDRS_NUM_OLD, SCTP_GET_PEER_ADDRS_OLD,
SCTP_GET_LOCAL_ADDRS_NUM_OLD, SCTP_GET_LOCAL_ADDRS_OLD
When: June 2009
Why: A newer version of the options have been introduced in 2005 that
removes the limitions of the old API. The sctp library has been
converted to use these new options at the same time. Any user
space app that directly uses the old options should convert to using
the new options.
Who: Vlad Yasevich <vladislav.yasevich@hp.com>
---------------------------
What: Ability for non root users to shm_get hugetlb pages based on mlock
What: Ability for non root users to shm_get hugetlb pages based on mlock
resource limits
resource limits
When: 2.6.31
When: 2.6.31
...
...
include/linux/sctp.h
View file @
5656b6ca
...
@@ -242,6 +242,7 @@ enum {
...
@@ -242,6 +242,7 @@ enum {
SCTP_DATA_FIRST_FRAG
=
0x02
,
SCTP_DATA_FIRST_FRAG
=
0x02
,
SCTP_DATA_NOT_FRAG
=
0x03
,
SCTP_DATA_NOT_FRAG
=
0x03
,
SCTP_DATA_UNORDERED
=
0x04
,
SCTP_DATA_UNORDERED
=
0x04
,
SCTP_DATA_SACK_IMM
=
0x08
,
};
};
enum
{
SCTP_DATA_FRAG_MASK
=
0x03
,
};
enum
{
SCTP_DATA_FRAG_MASK
=
0x03
,
};
...
...
include/net/sctp/constants.h
View file @
5656b6ca
...
@@ -308,6 +308,10 @@ enum { SCTP_MAX_GABS = 16 };
...
@@ -308,6 +308,10 @@ enum { SCTP_MAX_GABS = 16 };
#define SCTP_DEFAULT_MINWINDOW 1500
/* default minimum rwnd size */
#define SCTP_DEFAULT_MINWINDOW 1500
/* default minimum rwnd size */
#define SCTP_DEFAULT_MAXWINDOW 65535
/* default rwnd size */
#define SCTP_DEFAULT_MAXWINDOW 65535
/* default rwnd size */
#define SCTP_DEFAULT_RWND_SHIFT 4
/* by default, update on 1/16 of
* rcvbuf, which is 1/8 of initial
* window
*/
#define SCTP_DEFAULT_MAXSEGMENT 1500
/* MTU size, this is the limit
#define SCTP_DEFAULT_MAXSEGMENT 1500
/* MTU size, this is the limit
* to which we will raise the P-MTU.
* to which we will raise the P-MTU.
*/
*/
...
...
include/net/sctp/sm.h
View file @
5656b6ca
...
@@ -243,7 +243,8 @@ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *,
...
@@ -243,7 +243,8 @@ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *,
const
struct
sctp_chunk
*
chunk
,
const
struct
sctp_chunk
*
chunk
,
__be16
cause_code
,
__be16
cause_code
,
const
void
*
payload
,
const
void
*
payload
,
size_t
paylen
);
size_t
paylen
,
size_t
reserve_tail
);
struct
sctp_chunk
*
sctp_make_asconf_update_ip
(
struct
sctp_association
*
,
struct
sctp_chunk
*
sctp_make_asconf_update_ip
(
struct
sctp_association
*
,
union
sctp_addr
*
,
union
sctp_addr
*
,
...
...
include/net/sctp/structs.h
View file @
5656b6ca
...
@@ -231,6 +231,11 @@ extern struct sctp_globals {
...
@@ -231,6 +231,11 @@ extern struct sctp_globals {
/* Flag to indicate whether computing and verifying checksum
/* Flag to indicate whether computing and verifying checksum
* is disabled. */
* is disabled. */
int
checksum_disable
;
int
checksum_disable
;
/* Threshold for rwnd update SACKS. Receive buffer shifted this many
* bits is an indicator of when to send and window update SACK.
*/
int
rwnd_update_shift
;
}
sctp_globals
;
}
sctp_globals
;
#define sctp_rto_initial (sctp_globals.rto_initial)
#define sctp_rto_initial (sctp_globals.rto_initial)
...
@@ -267,6 +272,7 @@ extern struct sctp_globals {
...
@@ -267,6 +272,7 @@ extern struct sctp_globals {
#define sctp_prsctp_enable (sctp_globals.prsctp_enable)
#define sctp_prsctp_enable (sctp_globals.prsctp_enable)
#define sctp_auth_enable (sctp_globals.auth_enable)
#define sctp_auth_enable (sctp_globals.auth_enable)
#define sctp_checksum_disable (sctp_globals.checksum_disable)
#define sctp_checksum_disable (sctp_globals.checksum_disable)
#define sctp_rwnd_upd_shift (sctp_globals.rwnd_update_shift)
/* SCTP Socket type: UDP or TCP style. */
/* SCTP Socket type: UDP or TCP style. */
typedef
enum
{
typedef
enum
{
...
@@ -936,6 +942,8 @@ struct sctp_transport {
...
@@ -936,6 +942,8 @@ struct sctp_transport {
/* Data that has been sent, but not acknowledged. */
/* Data that has been sent, but not acknowledged. */
__u32
flight_size
;
__u32
flight_size
;
__u32
burst_limited
;
/* Holds old cwnd when max.burst is applied */
/* TSN marking the fast recovery exit point */
/* TSN marking the fast recovery exit point */
__u32
fast_recovery_exit
;
__u32
fast_recovery_exit
;
...
@@ -944,12 +952,6 @@ struct sctp_transport {
...
@@ -944,12 +952,6 @@ struct sctp_transport {
/* Source address. */
/* Source address. */
union
sctp_addr
saddr
;
union
sctp_addr
saddr
;
/* When was the last time(in jiffies) that a data packet was sent on
* this transport? This is used to adjust the cwnd when the transport
* becomes inactive.
*/
unsigned
long
last_time_used
;
/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
* the destination address every heartbeat interval.
* the destination address every heartbeat interval.
*/
*/
...
@@ -1070,6 +1072,8 @@ void sctp_transport_put(struct sctp_transport *);
...
@@ -1070,6 +1072,8 @@ void sctp_transport_put(struct sctp_transport *);
void
sctp_transport_update_rto
(
struct
sctp_transport
*
,
__u32
);
void
sctp_transport_update_rto
(
struct
sctp_transport
*
,
__u32
);
void
sctp_transport_raise_cwnd
(
struct
sctp_transport
*
,
__u32
,
__u32
);
void
sctp_transport_raise_cwnd
(
struct
sctp_transport
*
,
__u32
,
__u32
);
void
sctp_transport_lower_cwnd
(
struct
sctp_transport
*
,
sctp_lower_cwnd_t
);
void
sctp_transport_lower_cwnd
(
struct
sctp_transport
*
,
sctp_lower_cwnd_t
);
void
sctp_transport_burst_limited
(
struct
sctp_transport
*
);
void
sctp_transport_burst_reset
(
struct
sctp_transport
*
);
unsigned
long
sctp_transport_timeout
(
struct
sctp_transport
*
);
unsigned
long
sctp_transport_timeout
(
struct
sctp_transport
*
);
void
sctp_transport_reset
(
struct
sctp_transport
*
);
void
sctp_transport_reset
(
struct
sctp_transport
*
);
void
sctp_transport_update_pmtu
(
struct
sctp_transport
*
,
u32
);
void
sctp_transport_update_pmtu
(
struct
sctp_transport
*
,
u32
);
...
...
include/net/sctp/user.h
View file @
5656b6ca
...
@@ -60,96 +60,49 @@ typedef __s32 sctp_assoc_t;
...
@@ -60,96 +60,49 @@ typedef __s32 sctp_assoc_t;
/* The following symbols come from the Sockets API Extensions for
/* The following symbols come from the Sockets API Extensions for
* SCTP <draft-ietf-tsvwg-sctpsocket-07.txt>.
* SCTP <draft-ietf-tsvwg-sctpsocket-07.txt>.
*/
*/
enum
sctp_optname
{
#define SCTP_RTOINFO 0
SCTP_RTOINFO
,
#define SCTP_ASSOCINFO 1
#define SCTP_RTOINFO SCTP_RTOINFO
#define SCTP_INITMSG 2
SCTP_ASSOCINFO
,
#define SCTP_NODELAY 3
/* Get/set nodelay option. */
#define SCTP_ASSOCINFO SCTP_ASSOCINFO
#define SCTP_AUTOCLOSE 4
SCTP_INITMSG
,
#define SCTP_SET_PEER_PRIMARY_ADDR 5
#define SCTP_INITMSG SCTP_INITMSG
#define SCTP_PRIMARY_ADDR 6
SCTP_NODELAY
,
/* Get/set nodelay option. */
#define SCTP_ADAPTATION_LAYER 7
#define SCTP_NODELAY SCTP_NODELAY
#define SCTP_DISABLE_FRAGMENTS 8
SCTP_AUTOCLOSE
,
#define SCTP_PEER_ADDR_PARAMS 9
#define SCTP_AUTOCLOSE SCTP_AUTOCLOSE
#define SCTP_DEFAULT_SEND_PARAM 10
SCTP_SET_PEER_PRIMARY_ADDR
,
#define SCTP_EVENTS 11
#define SCTP_SET_PEER_PRIMARY_ADDR SCTP_SET_PEER_PRIMARY_ADDR
#define SCTP_I_WANT_MAPPED_V4_ADDR 12
/* Turn on/off mapped v4 addresses */
SCTP_PRIMARY_ADDR
,
#define SCTP_MAXSEG 13
/* Get/set maximum fragment. */
#define SCTP_PRIMARY_ADDR SCTP_PRIMARY_ADDR
#define SCTP_STATUS 14
SCTP_ADAPTATION_LAYER
,
#define SCTP_GET_PEER_ADDR_INFO 15
#define SCTP_ADAPTATION_LAYER SCTP_ADAPTATION_LAYER
#define SCTP_DELAYED_ACK_TIME 16
SCTP_DISABLE_FRAGMENTS
,
#define SCTP_DELAYED_ACK SCTP_DELAYED_ACK_TIME
#define SCTP_DISABLE_FRAGMENTS SCTP_DISABLE_FRAGMENTS
#define SCTP_CONTEXT 17
SCTP_PEER_ADDR_PARAMS
,
#define SCTP_FRAGMENT_INTERLEAVE 18
#define SCTP_PEER_ADDR_PARAMS SCTP_PEER_ADDR_PARAMS
#define SCTP_PARTIAL_DELIVERY_POINT 19
/* Set/Get partial delivery point */
SCTP_DEFAULT_SEND_PARAM
,
#define SCTP_MAX_BURST 20
/* Set/Get max burst */
#define SCTP_DEFAULT_SEND_PARAM SCTP_DEFAULT_SEND_PARAM
#define SCTP_AUTH_CHUNK 21
/* Set only: add a chunk type to authenticate */
SCTP_EVENTS
,
#define SCTP_HMAC_IDENT 22
#define SCTP_EVENTS SCTP_EVENTS
#define SCTP_AUTH_KEY 23
SCTP_I_WANT_MAPPED_V4_ADDR
,
/* Turn on/off mapped v4 addresses */
#define SCTP_AUTH_ACTIVE_KEY 24
#define SCTP_I_WANT_MAPPED_V4_ADDR SCTP_I_WANT_MAPPED_V4_ADDR
#define SCTP_AUTH_DELETE_KEY 25
SCTP_MAXSEG
,
/* Get/set maximum fragment. */
#define SCTP_PEER_AUTH_CHUNKS 26
/* Read only */
#define SCTP_MAXSEG SCTP_MAXSEG
#define SCTP_LOCAL_AUTH_CHUNKS 27
/* Read only */
SCTP_STATUS
,
#define SCTP_GET_ASSOC_NUMBER 28
/* Read only */
#define SCTP_STATUS SCTP_STATUS
SCTP_GET_PEER_ADDR_INFO
,
/* Internal Socket Options. Some of the sctp library functions are
#define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO
SCTP_DELAYED_ACK
,
#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK
#define SCTP_DELAYED_ACK SCTP_DELAYED_ACK
SCTP_CONTEXT
,
/* Receive Context */
#define SCTP_CONTEXT SCTP_CONTEXT
SCTP_FRAGMENT_INTERLEAVE
,
#define SCTP_FRAGMENT_INTERLEAVE SCTP_FRAGMENT_INTERLEAVE
SCTP_PARTIAL_DELIVERY_POINT
,
/* Set/Get partial delivery point */
#define SCTP_PARTIAL_DELIVERY_POINT SCTP_PARTIAL_DELIVERY_POINT
SCTP_MAX_BURST
,
/* Set/Get max burst */
#define SCTP_MAX_BURST SCTP_MAX_BURST
SCTP_AUTH_CHUNK
,
/* Set only: add a chunk type to authenticat */
#define SCTP_AUTH_CHUNK SCTP_AUTH_CHUNK
SCTP_HMAC_IDENT
,
#define SCTP_HMAC_IDENT SCTP_HMAC_IDENT
SCTP_AUTH_KEY
,
#define SCTP_AUTH_KEY SCTP_AUTH_KEY
SCTP_AUTH_ACTIVE_KEY
,
#define SCTP_AUTH_ACTIVE_KEY SCTP_AUTH_ACTIVE_KEY
SCTP_AUTH_DELETE_KEY
,
#define SCTP_AUTH_DELETE_KEY SCTP_AUTH_DELETE_KEY
SCTP_PEER_AUTH_CHUNKS
,
/* Read only */
#define SCTP_PEER_AUTH_CHUNKS SCTP_PEER_AUTH_CHUNKS
SCTP_LOCAL_AUTH_CHUNKS
,
/* Read only */
#define SCTP_LOCAL_AUTH_CHUNKS SCTP_LOCAL_AUTH_CHUNKS
SCTP_GET_ASSOC_NUMBER
,
/* Read only */
#define SCTP_GET_ASSOC_NUMBER SCTP_GET_ASSOC_NUMBER
/* Internal Socket Options. Some of the sctp library functions are
* implemented using these socket options.
* implemented using these socket options.
*/
*/
SCTP_SOCKOPT_BINDX_ADD
=
100
,
/* BINDX requests for adding addresses. */
#define SCTP_SOCKOPT_BINDX_ADD 100
/* BINDX requests for adding addrs */
#define SCTP_SOCKOPT_BINDX_ADD SCTP_SOCKOPT_BINDX_ADD
#define SCTP_SOCKOPT_BINDX_REM 101
/* BINDX requests for removing addrs. */
SCTP_SOCKOPT_BINDX_REM
,
/* BINDX requests for removing addresses. */
#define SCTP_SOCKOPT_PEELOFF 102
/* peel off association. */
#define SCTP_SOCKOPT_BINDX_REM SCTP_SOCKOPT_BINDX_REM
/* Options 104-106 are deprecated and removed. Do not use this space */
SCTP_SOCKOPT_PEELOFF
,
/* peel off association. */
#define SCTP_SOCKOPT_CONNECTX_OLD 107
/* CONNECTX old requests. */
#define SCTP_SOCKOPT_PEELOFF SCTP_SOCKOPT_PEELOFF
#define SCTP_GET_PEER_ADDRS 108
/* Get all peer addresss. */
SCTP_GET_PEER_ADDRS_NUM_OLD
,
/* Get number of peer addresss. */
#define SCTP_GET_LOCAL_ADDRS 109
/* Get all local addresss. */
#define SCTP_GET_PEER_ADDRS_NUM_OLD SCTP_GET_PEER_ADDRS_NUM_OLD
#define SCTP_SOCKOPT_CONNECTX 110
/* CONNECTX requests. */
SCTP_GET_PEER_ADDRS_OLD
,
/* Get all peer addresss. */
#define SCTP_SOCKOPT_CONNECTX3 111
/* CONNECTX requests (updated) */
#define SCTP_GET_PEER_ADDRS_OLD SCTP_GET_PEER_ADDRS_OLD
SCTP_GET_LOCAL_ADDRS_NUM_OLD
,
/* Get number of local addresss. */
#define SCTP_GET_LOCAL_ADDRS_NUM_OLD SCTP_GET_LOCAL_ADDRS_NUM_OLD
SCTP_GET_LOCAL_ADDRS_OLD
,
/* Get all local addresss. */
#define SCTP_GET_LOCAL_ADDRS_OLD SCTP_GET_LOCAL_ADDRS_OLD
SCTP_SOCKOPT_CONNECTX_OLD
,
/* CONNECTX old requests. */
#define SCTP_SOCKOPT_CONNECTX_OLD SCTP_SOCKOPT_CONNECTX_OLD
SCTP_GET_PEER_ADDRS
,
/* Get all peer addresss. */
#define SCTP_GET_PEER_ADDRS SCTP_GET_PEER_ADDRS
SCTP_GET_LOCAL_ADDRS
,
/* Get all local addresss. */
#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS
SCTP_SOCKOPT_CONNECTX
,
/* CONNECTX requests. */
#define SCTP_SOCKOPT_CONNECTX SCTP_SOCKOPT_CONNECTX
SCTP_SOCKOPT_CONNECTX3
,
/* CONNECTX requests. (new implementation) */
#define SCTP_SOCKOPT_CONNECTX3 SCTP_SOCKOPT_CONNECTX3
};
/*
/*
* 5.2.1 SCTP Initiation Structure (SCTP_INIT)
* 5.2.1 SCTP Initiation Structure (SCTP_INIT)
...
@@ -206,6 +159,7 @@ enum sctp_sinfo_flags {
...
@@ -206,6 +159,7 @@ enum sctp_sinfo_flags {
SCTP_UNORDERED
=
1
,
/* Send/receive message unordered. */
SCTP_UNORDERED
=
1
,
/* Send/receive message unordered. */
SCTP_ADDR_OVER
=
2
,
/* Override the primary destination. */
SCTP_ADDR_OVER
=
2
,
/* Override the primary destination. */
SCTP_ABORT
=
4
,
/* Send an ABORT message to the peer. */
SCTP_ABORT
=
4
,
/* Send an ABORT message to the peer. */
SCTP_SACK_IMMEDIATELY
=
8
,
/* SACK should be sent without delay */
SCTP_EOF
=
MSG_FIN
,
/* Initiate graceful shutdown process. */
SCTP_EOF
=
MSG_FIN
,
/* Initiate graceful shutdown process. */
};
};
...
...
net/sctp/associola.c
View file @
5656b6ca
...
@@ -63,6 +63,12 @@
...
@@ -63,6 +63,12 @@
static
void
sctp_assoc_bh_rcv
(
struct
work_struct
*
work
);
static
void
sctp_assoc_bh_rcv
(
struct
work_struct
*
work
);
static
void
sctp_assoc_free_asconf_acks
(
struct
sctp_association
*
asoc
);
static
void
sctp_assoc_free_asconf_acks
(
struct
sctp_association
*
asoc
);
/* Keep track of the new idr low so that we don't re-use association id
* numbers too fast. It is protected by they idr spin lock is in the
* range of 1 - INT_MAX.
*/
static
u32
idr_low
=
1
;
/* 1st Level Abstractions. */
/* 1st Level Abstractions. */
...
@@ -167,7 +173,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
...
@@ -167,7 +173,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_HEARTBEAT
]
=
0
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_HEARTBEAT
]
=
0
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_SACK
]
=
asoc
->
sackdelay
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_SACK
]
=
asoc
->
sackdelay
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
]
=
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
]
=
sp
->
autoclose
*
HZ
;
(
unsigned
long
)
sp
->
autoclose
*
HZ
;
/* Initilizes the timers */
/* Initilizes the timers */
for
(
i
=
SCTP_EVENT_TIMEOUT_NONE
;
i
<
SCTP_NUM_TIMEOUT_TYPES
;
++
i
)
for
(
i
=
SCTP_EVENT_TIMEOUT_NONE
;
i
<
SCTP_NUM_TIMEOUT_TYPES
;
++
i
)
...
@@ -512,7 +518,13 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
...
@@ -512,7 +518,13 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
* to this destination address earlier. The sender MUST set
* to this destination address earlier. The sender MUST set
* CYCLING_CHANGEOVER to indicate that this switch is a
* CYCLING_CHANGEOVER to indicate that this switch is a
* double switch to the same destination address.
* double switch to the same destination address.
*
* Really, only bother is we have data queued or outstanding on
* the association.
*/
*/
if
(
!
asoc
->
outqueue
.
outstanding_bytes
&&
!
asoc
->
outqueue
.
out_qlen
)
return
;
if
(
transport
->
cacc
.
changeover_active
)
if
(
transport
->
cacc
.
changeover_active
)
transport
->
cacc
.
cycling_changeover
=
changeover
;
transport
->
cacc
.
cycling_changeover
=
changeover
;
...
@@ -732,6 +744,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
...
@@ -732,6 +744,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
peer
->
partial_bytes_acked
=
0
;
peer
->
partial_bytes_acked
=
0
;
peer
->
flight_size
=
0
;
peer
->
flight_size
=
0
;
peer
->
burst_limited
=
0
;
/* Set the transport's RTO.initial value */
/* Set the transport's RTO.initial value */
peer
->
rto
=
asoc
->
rto_initial
;
peer
->
rto
=
asoc
->
rto_initial
;
...
@@ -1377,8 +1390,9 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc)
...
@@ -1377,8 +1390,9 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc)
case
SCTP_STATE_SHUTDOWN_RECEIVED
:
case
SCTP_STATE_SHUTDOWN_RECEIVED
:
case
SCTP_STATE_SHUTDOWN_SENT
:
case
SCTP_STATE_SHUTDOWN_SENT
:
if
((
asoc
->
rwnd
>
asoc
->
a_rwnd
)
&&
if
((
asoc
->
rwnd
>
asoc
->
a_rwnd
)
&&
((
asoc
->
rwnd
-
asoc
->
a_rwnd
)
>=
((
asoc
->
rwnd
-
asoc
->
a_rwnd
)
>=
max_t
(
__u32
,
min_t
(
__u32
,
(
asoc
->
base
.
sk
->
sk_rcvbuf
>>
1
),
asoc
->
pathmtu
)))
(
asoc
->
base
.
sk
->
sk_rcvbuf
>>
sctp_rwnd_upd_shift
),
asoc
->
pathmtu
)))
return
1
;
return
1
;
break
;
break
;
default:
default:
...
@@ -1545,7 +1559,12 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
...
@@ -1545,7 +1559,12 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
spin_lock_bh
(
&
sctp_assocs_id_lock
);
spin_lock_bh
(
&
sctp_assocs_id_lock
);
error
=
idr_get_new_above
(
&
sctp_assocs_id
,
(
void
*
)
asoc
,
error
=
idr_get_new_above
(
&
sctp_assocs_id
,
(
void
*
)
asoc
,
1
,
&
assoc_id
);
idr_low
,
&
assoc_id
);
if
(
!
error
)
{
idr_low
=
assoc_id
+
1
;
if
(
idr_low
==
INT_MAX
)
idr_low
=
1
;
}
spin_unlock_bh
(
&
sctp_assocs_id_lock
);
spin_unlock_bh
(
&
sctp_assocs_id_lock
);
if
(
error
==
-
EAGAIN
)
if
(
error
==
-
EAGAIN
)
goto
retry
;
goto
retry
;
...
...
net/sctp/chunk.c
View file @
5656b6ca
...
@@ -263,9 +263,18 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
...
@@ -263,9 +263,18 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
if
(
0
==
i
)
if
(
0
==
i
)
frag
|=
SCTP_DATA_FIRST_FRAG
;
frag
|=
SCTP_DATA_FIRST_FRAG
;
if
((
i
==
(
whole
-
1
))
&&
!
over
)
if
((
i
==
(
whole
-
1
))
&&
!
over
)
{
frag
|=
SCTP_DATA_LAST_FRAG
;
frag
|=
SCTP_DATA_LAST_FRAG
;
/* The application requests to set the I-bit of the
* last DATA chunk of a user message when providing
* the user message to the SCTP implementation.
*/
if
((
sinfo
->
sinfo_flags
&
SCTP_EOF
)
||
(
sinfo
->
sinfo_flags
&
SCTP_SACK_IMMEDIATELY
))
frag
|=
SCTP_DATA_SACK_IMM
;
}
chunk
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
len
,
frag
,
0
);
chunk
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
len
,
frag
,
0
);
if
(
!
chunk
)
if
(
!
chunk
)
...
@@ -297,6 +306,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
...
@@ -297,6 +306,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
else
else
frag
=
SCTP_DATA_LAST_FRAG
;
frag
=
SCTP_DATA_LAST_FRAG
;
if
((
sinfo
->
sinfo_flags
&
SCTP_EOF
)
||
(
sinfo
->
sinfo_flags
&
SCTP_SACK_IMMEDIATELY
))
frag
|=
SCTP_DATA_SACK_IMM
;
chunk
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
over
,
frag
,
0
);
chunk
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
over
,
frag
,
0
);
if
(
!
chunk
)
if
(
!
chunk
)
...
...
net/sctp/output.c
View file @
5656b6ca
...
@@ -429,9 +429,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -429,9 +429,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
list_del_init
(
&
chunk
->
list
);
list_del_init
(
&
chunk
->
list
);
if
(
sctp_chunk_is_data
(
chunk
))
{
if
(
sctp_chunk_is_data
(
chunk
))
{
if
(
!
chunk
->
has_tsn
)
{
if
(
!
chunk
->
resent
)
{
sctp_chunk_assign_ssn
(
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
* by rule C5, a new RTT measurement MUST be made each
* by rule C5, a new RTT measurement MUST be made each
...
@@ -444,7 +442,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -444,7 +442,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
chunk
->
rtt_in_progress
=
1
;
chunk
->
rtt_in_progress
=
1
;
tp
->
rto_pending
=
1
;
tp
->
rto_pending
=
1
;
}
}
}
else
}
chunk
->
resent
=
1
;
chunk
->
resent
=
1
;
has_data
=
1
;
has_data
=
1
;
...
@@ -557,8 +556,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -557,8 +556,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
struct
timer_list
*
timer
;
struct
timer_list
*
timer
;
unsigned
long
timeout
;
unsigned
long
timeout
;
tp
->
last_time_used
=
jiffies
;
/* Restart the AUTOCLOSE timer when sending data. */
/* Restart the AUTOCLOSE timer when sending data. */
if
(
sctp_state
(
asoc
,
ESTABLISHED
)
&&
asoc
->
autoclose
)
{
if
(
sctp_state
(
asoc
,
ESTABLISHED
)
&&
asoc
->
autoclose
)
{
timer
=
&
asoc
->
timers
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
];
timer
=
&
asoc
->
timers
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
];
...
@@ -617,7 +614,6 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
...
@@ -617,7 +614,6 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
sctp_xmit_t
retval
=
SCTP_XMIT_OK
;
sctp_xmit_t
retval
=
SCTP_XMIT_OK
;
size_t
datasize
,
rwnd
,
inflight
,
flight_size
;
size_t
datasize
,
rwnd
,
inflight
,
flight_size
;
struct
sctp_transport
*
transport
=
packet
->
transport
;
struct
sctp_transport
*
transport
=
packet
->
transport
;
__u32
max_burst_bytes
;
struct
sctp_association
*
asoc
=
transport
->
asoc
;
struct
sctp_association
*
asoc
=
transport
->
asoc
;
struct
sctp_outq
*
q
=
&
asoc
->
outqueue
;
struct
sctp_outq
*
q
=
&
asoc
->
outqueue
;
...
@@ -650,28 +646,6 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
...
@@ -650,28 +646,6 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
}
}
}
}
/* sctpimpguide-05 2.14.2
* D) When the time comes for the sender to
* transmit new DATA chunks, the protocol parameter Max.Burst MUST
* first be applied to limit how many new DATA chunks may be sent.
* The limit is applied by adjusting cwnd as follows:
* if ((flightsize + Max.Burst * MTU) < cwnd)
* cwnd = flightsize + Max.Burst * MTU
*/
max_burst_bytes
=
asoc
->
max_burst
*
asoc
->
pathmtu
;
if
((
flight_size
+
max_burst_bytes
)
<
transport
->
cwnd
)
{
transport
->
cwnd
=
flight_size
+
max_burst_bytes
;
SCTP_DEBUG_PRINTK
(
"%s: cwnd limited by max_burst: "
"transport: %p, cwnd: %d, "
"ssthresh: %d, flight_size: %d, "
"pba: %d
\n
"
,
__func__
,
transport
,
transport
->
cwnd
,
transport
->
ssthresh
,
transport
->
flight_size
,
transport
->
partial_bytes_acked
);
}
/* RFC 2960 6.1 Transmission of DATA Chunks
/* RFC 2960 6.1 Transmission of DATA Chunks
*
*
* B) At any given time, the sender MUST NOT transmit new data
* B) At any given time, the sender MUST NOT transmit new data
...
@@ -747,6 +721,8 @@ static void sctp_packet_append_data(struct sctp_packet *packet,
...
@@ -747,6 +721,8 @@ static void sctp_packet_append_data(struct sctp_packet *packet,
/* Has been accepted for transmission. */
/* Has been accepted for transmission. */
if
(
!
asoc
->
peer
.
prsctp_capable
)
if
(
!
asoc
->
peer
.
prsctp_capable
)
chunk
->
msg
->
can_abandon
=
0
;
chunk
->
msg
->
can_abandon
=
0
;
sctp_chunk_assign_tsn
(
chunk
);
sctp_chunk_assign_ssn
(
chunk
);
}
}
static
sctp_xmit_t
sctp_packet_will_fit
(
struct
sctp_packet
*
packet
,
static
sctp_xmit_t
sctp_packet_will_fit
(
struct
sctp_packet
*
packet
,
...
...
net/sctp/outqueue.c
View file @
5656b6ca
...
@@ -931,6 +931,14 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -931,6 +931,14 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
goto
sctp_flush_out
;
goto
sctp_flush_out
;
}
}
/* Apply Max.Burst limitation to the current transport in
* case it will be used for new data. We are going to
* rest it before we return, but we want to apply the limit
* to the currently queued data.
*/
if
(
transport
)
sctp_transport_burst_limited
(
transport
);
/* Finally, transmit new packets. */
/* Finally, transmit new packets. */
while
((
chunk
=
sctp_outq_dequeue_data
(
q
))
!=
NULL
)
{
while
((
chunk
=
sctp_outq_dequeue_data
(
q
))
!=
NULL
)
{
/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
...
@@ -976,6 +984,10 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -976,6 +984,10 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
packet
=
&
transport
->
packet
;
packet
=
&
transport
->
packet
;
sctp_packet_config
(
packet
,
vtag
,
sctp_packet_config
(
packet
,
vtag
,
asoc
->
peer
.
ecn_capable
);
asoc
->
peer
.
ecn_capable
);
/* We've switched transports, so apply the
* Burst limit to the new transport.
*/
sctp_transport_burst_limited
(
transport
);
}
}
SCTP_DEBUG_PRINTK
(
"sctp_outq_flush(%p, %p[%s]), "
,
SCTP_DEBUG_PRINTK
(
"sctp_outq_flush(%p, %p[%s]), "
,
...
@@ -1011,6 +1023,13 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -1011,6 +1023,13 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
break
;
break
;
case
SCTP_XMIT_OK
:
case
SCTP_XMIT_OK
:
/* The sender is in the SHUTDOWN-PENDING state,
* The sender MAY set the I-bit in the DATA
* chunk header.
*/
if
(
asoc
->
state
==
SCTP_STATE_SHUTDOWN_PENDING
)
chunk
->
chunk_hdr
->
flags
|=
SCTP_DATA_SACK_IMM
;
break
;
break
;
default:
default:
...
@@ -1063,6 +1082,9 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -1063,6 +1082,9 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
packet
=
&
t
->
packet
;
packet
=
&
t
->
packet
;
if
(
!
sctp_packet_empty
(
packet
))
if
(
!
sctp_packet_empty
(
packet
))
error
=
sctp_packet_transmit
(
packet
);
error
=
sctp_packet_transmit
(
packet
);
/* Clear the burst limited state, if any */
sctp_transport_burst_reset
(
t
);
}
}
return
error
;
return
error
;
...
...
net/sctp/protocol.c
View file @
5656b6ca
...
@@ -1258,6 +1258,9 @@ SCTP_STATIC __init int sctp_init(void)
...
@@ -1258,6 +1258,9 @@ SCTP_STATIC __init int sctp_init(void)
/* Set SCOPE policy to enabled */
/* Set SCOPE policy to enabled */
sctp_scope_policy
=
SCTP_SCOPE_POLICY_ENABLE
;
sctp_scope_policy
=
SCTP_SCOPE_POLICY_ENABLE
;
/* Set the default rwnd update threshold */
sctp_rwnd_upd_shift
=
SCTP_DEFAULT_RWND_SHIFT
;
sctp_sysctl_register
();
sctp_sysctl_register
();
INIT_LIST_HEAD
(
&
sctp_address_families
);
INIT_LIST_HEAD
(
&
sctp_address_families
);
...
...
net/sctp/sm_make_chunk.c
View file @
5656b6ca
...
@@ -987,7 +987,10 @@ static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
...
@@ -987,7 +987,10 @@ static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
target
=
skb_put
(
chunk
->
skb
,
len
);
target
=
skb_put
(
chunk
->
skb
,
len
);
if
(
data
)
memcpy
(
target
,
data
,
len
);
memcpy
(
target
,
data
,
len
);
else
memset
(
target
,
0
,
len
);
/* Adjust the chunk length field. */
/* Adjust the chunk length field. */
chunk
->
chunk_hdr
->
length
=
htons
(
chunklen
+
len
);
chunk
->
chunk_hdr
->
length
=
htons
(
chunklen
+
len
);
...
@@ -1129,16 +1132,18 @@ static struct sctp_chunk *sctp_make_op_error_space(
...
@@ -1129,16 +1132,18 @@ static struct sctp_chunk *sctp_make_op_error_space(
struct
sctp_chunk
*
sctp_make_op_error
(
const
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
sctp_make_op_error
(
const
struct
sctp_association
*
asoc
,
const
struct
sctp_chunk
*
chunk
,
const
struct
sctp_chunk
*
chunk
,
__be16
cause_code
,
const
void
*
payload
,
__be16
cause_code
,
const
void
*
payload
,
size_t
paylen
)
size_t
paylen
,
size_t
reserve_tail
)
{
{
struct
sctp_chunk
*
retval
;
struct
sctp_chunk
*
retval
;
retval
=
sctp_make_op_error_space
(
asoc
,
chunk
,
paylen
);
retval
=
sctp_make_op_error_space
(
asoc
,
chunk
,
paylen
+
reserve_tail
);
if
(
!
retval
)
if
(
!
retval
)
goto
nodata
;
goto
nodata
;
sctp_init_cause
(
retval
,
cause_code
,
paylen
);
sctp_init_cause
(
retval
,
cause_code
,
paylen
+
reserve_tail
);
sctp_addto_chunk
(
retval
,
paylen
,
payload
);
sctp_addto_chunk
(
retval
,
paylen
,
payload
);
if
(
reserve_tail
)
sctp_addto_param
(
retval
,
reserve_tail
,
NULL
);
nodata:
nodata:
return
retval
;
return
retval
;
...
...
net/sctp/sm_sideeffect.c
View file @
5656b6ca
...
@@ -217,7 +217,6 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
...
@@ -217,7 +217,6 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_SACK
));
SCTP_TO
(
SCTP_EVENT_TIMEOUT_SACK
));
}
else
{
}
else
{
if
(
asoc
->
a_rwnd
>
asoc
->
rwnd
)
asoc
->
a_rwnd
=
asoc
->
rwnd
;
asoc
->
a_rwnd
=
asoc
->
rwnd
;
sack
=
sctp_make_sack
(
asoc
);
sack
=
sctp_make_sack
(
asoc
);
if
(
!
sack
)
if
(
!
sack
)
...
@@ -1418,6 +1417,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
...
@@ -1418,6 +1417,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
asoc
->
init_last_sent_to
=
t
;
asoc
->
init_last_sent_to
=
t
;
chunk
->
transport
=
t
;
chunk
->
transport
=
t
;
t
->
init_sent_count
++
;
t
->
init_sent_count
++
;
/* Set the new transport as primary */
sctp_assoc_set_primary
(
asoc
,
t
);
break
;
break
;
case
SCTP_CMD_INIT_RESTART
:
case
SCTP_CMD_INIT_RESTART
:
...
...
net/sctp/sm_statefuns.c
View file @
5656b6ca
...
@@ -996,14 +996,15 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
...
@@ -996,14 +996,15 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
sctp_sf_heartbeat
(
ep
,
asoc
,
type
,
arg
,
sctp_sf_heartbeat
(
ep
,
asoc
,
type
,
arg
,
commands
))
commands
))
return
SCTP_DISPOSITION_NOMEM
;
return
SCTP_DISPOSITION_NOMEM
;
/* Set transport error counter and association error counter
/* Set transport error counter and association error counter
* when sending heartbeat.
* when sending heartbeat.
*/
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSPORT_IDLE
,
SCTP_TRANSPORT
(
transport
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSPORT_HB_SENT
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSPORT_HB_SENT
,
SCTP_TRANSPORT
(
transport
));
SCTP_TRANSPORT
(
transport
));
}
}
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSPORT_IDLE
,
SCTP_TRANSPORT
(
transport
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_HB_TIMER_UPDATE
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_HB_TIMER_UPDATE
,
SCTP_TRANSPORT
(
transport
));
SCTP_TRANSPORT
(
transport
));
...
@@ -1720,7 +1721,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
...
@@ -1720,7 +1721,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
err
=
sctp_make_op_error
(
asoc
,
chunk
,
err
=
sctp_make_op_error
(
asoc
,
chunk
,
SCTP_ERROR_COOKIE_IN_SHUTDOWN
,
SCTP_ERROR_COOKIE_IN_SHUTDOWN
,
NULL
,
0
);
NULL
,
0
,
0
);
if
(
err
)
if
(
err
)
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
err
));
SCTP_CHUNK
(
err
));
...
@@ -2868,6 +2869,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
...
@@ -2868,6 +2869,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
struct
sctp_chunk
*
chunk
=
arg
;
struct
sctp_chunk
*
chunk
=
arg
;
sctp_arg_t
force
=
SCTP_NOFORCE
();
int
error
;
int
error
;
if
(
!
sctp_vtag_verify
(
chunk
,
asoc
))
{
if
(
!
sctp_vtag_verify
(
chunk
,
asoc
))
{
...
@@ -2901,6 +2903,9 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
...
@@ -2901,6 +2903,9 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
BUG
();
BUG
();
}
}
if
(
chunk
->
chunk_hdr
->
flags
&
SCTP_DATA_SACK_IMM
)
force
=
SCTP_FORCE
();
if
(
asoc
->
autoclose
)
{
if
(
asoc
->
autoclose
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_AUTOCLOSE
));
SCTP_TO
(
SCTP_EVENT_TIMEOUT_AUTOCLOSE
));
...
@@ -2929,7 +2934,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
...
@@ -2929,7 +2934,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
* more aggressive than the following algorithms allow.
* more aggressive than the following algorithms allow.
*/
*/
if
(
chunk
->
end_of_packet
)
if
(
chunk
->
end_of_packet
)
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_GEN_SACK
,
SCTP_NOFORCE
()
);
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_GEN_SACK
,
force
);
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
...
@@ -2954,7 +2959,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
...
@@ -2954,7 +2959,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
discard_noforce:
discard_noforce:
if
(
chunk
->
end_of_packet
)
if
(
chunk
->
end_of_packet
)
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_GEN_SACK
,
SCTP_NOFORCE
()
);
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_GEN_SACK
,
force
);
return
SCTP_DISPOSITION_DISCARD
;
return
SCTP_DISPOSITION_DISCARD
;
consume:
consume:
...
@@ -3973,7 +3978,7 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
...
@@ -3973,7 +3978,7 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
err_chunk
=
sctp_make_op_error
(
asoc
,
chunk
,
err_chunk
=
sctp_make_op_error
(
asoc
,
chunk
,
SCTP_ERROR_UNSUP_HMAC
,
SCTP_ERROR_UNSUP_HMAC
,
&
auth_hdr
->
hmac_id
,
&
auth_hdr
->
hmac_id
,
sizeof
(
__u16
));
sizeof
(
__u16
)
,
0
);
if
(
err_chunk
)
{
if
(
err_chunk
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
err_chunk
));
SCTP_CHUNK
(
err_chunk
));
...
@@ -4065,7 +4070,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
...
@@ -4065,7 +4070,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
hdr
=
unk_chunk
->
chunk_hdr
;
hdr
=
unk_chunk
->
chunk_hdr
;
err_chunk
=
sctp_make_op_error
(
asoc
,
unk_chunk
,
err_chunk
=
sctp_make_op_error
(
asoc
,
unk_chunk
,
SCTP_ERROR_UNKNOWN_CHUNK
,
hdr
,
SCTP_ERROR_UNKNOWN_CHUNK
,
hdr
,
WORD_ROUND
(
ntohs
(
hdr
->
length
)));
WORD_ROUND
(
ntohs
(
hdr
->
length
)),
0
);
if
(
err_chunk
)
{
if
(
err_chunk
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
err_chunk
));
SCTP_CHUNK
(
err_chunk
));
...
@@ -4084,7 +4090,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
...
@@ -4084,7 +4090,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
hdr
=
unk_chunk
->
chunk_hdr
;
hdr
=
unk_chunk
->
chunk_hdr
;
err_chunk
=
sctp_make_op_error
(
asoc
,
unk_chunk
,
err_chunk
=
sctp_make_op_error
(
asoc
,
unk_chunk
,
SCTP_ERROR_UNKNOWN_CHUNK
,
hdr
,
SCTP_ERROR_UNKNOWN_CHUNK
,
hdr
,
WORD_ROUND
(
ntohs
(
hdr
->
length
)));
WORD_ROUND
(
ntohs
(
hdr
->
length
)),
0
);
if
(
err_chunk
)
{
if
(
err_chunk
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
err_chunk
));
SCTP_CHUNK
(
err_chunk
));
...
@@ -6048,7 +6055,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
...
@@ -6048,7 +6055,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
err
=
sctp_make_op_error
(
asoc
,
chunk
,
SCTP_ERROR_INV_STRM
,
err
=
sctp_make_op_error
(
asoc
,
chunk
,
SCTP_ERROR_INV_STRM
,
&
data_hdr
->
stream
,
&
data_hdr
->
stream
,
sizeof
(
data_hdr
->
stream
));
sizeof
(
data_hdr
->
stream
),
sizeof
(
u16
));
if
(
err
)
if
(
err
)
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
err
));
SCTP_CHUNK
(
err
));
...
...
net/sctp/socket.c
View file @
5656b6ca
...
@@ -2086,6 +2086,9 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
...
@@ -2086,6 +2086,9 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
return
-
EINVAL
;
return
-
EINVAL
;
if
(
copy_from_user
(
&
sp
->
autoclose
,
optval
,
optlen
))
if
(
copy_from_user
(
&
sp
->
autoclose
,
optval
,
optlen
))
return
-
EFAULT
;
return
-
EFAULT
;
/* make sure it won't exceed MAX_SCHEDULE_TIMEOUT */
if
(
sp
->
autoclose
>
(
MAX_SCHEDULE_TIMEOUT
/
HZ
)
)
sp
->
autoclose
=
MAX_SCHEDULE_TIMEOUT
/
HZ
;
return
0
;
return
0
;
}
}
...
@@ -2311,11 +2314,10 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
...
@@ -2311,11 +2314,10 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
}
}
}
}
/* Note that unless the spp_flag is set to SPP_PMTUD_ENABLE the value
/* Note that a value of zero indicates the current setting should be
* of this field is ignored. Note also that a value of zero
left unchanged.
* indicates the current setting should be left unchanged.
*/
*/
if
(
(
params
->
spp_flags
&
SPP_PMTUD_ENABLE
)
&&
params
->
spp_pathmaxrxt
)
{
if
(
params
->
spp_pathmaxrxt
)
{
if
(
trans
)
{
if
(
trans
)
{
trans
->
pathmaxrxt
=
params
->
spp_pathmaxrxt
;
trans
->
pathmaxrxt
=
params
->
spp_pathmaxrxt
;
}
else
if
(
asoc
)
{
}
else
if
(
asoc
)
{
...
@@ -4349,90 +4351,6 @@ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval
...
@@ -4349,90 +4351,6 @@ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval
return
0
;
return
0
;
}
}
static
int
sctp_getsockopt_peer_addrs_num_old
(
struct
sock
*
sk
,
int
len
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
sctp_assoc_t
id
;
struct
sctp_association
*
asoc
;
struct
list_head
*
pos
;
int
cnt
=
0
;
if
(
len
<
sizeof
(
sctp_assoc_t
))
return
-
EINVAL
;
if
(
copy_from_user
(
&
id
,
optval
,
sizeof
(
sctp_assoc_t
)))
return
-
EFAULT
;
printk
(
KERN_WARNING
"SCTP: Use of SCTP_GET_PEER_ADDRS_NUM_OLD "
"socket option deprecated
\n
"
);
/* For UDP-style sockets, id specifies the association to query. */
asoc
=
sctp_id2assoc
(
sk
,
id
);
if
(
!
asoc
)
return
-
EINVAL
;
list_for_each
(
pos
,
&
asoc
->
peer
.
transport_addr_list
)
{
cnt
++
;
}
return
cnt
;
}
/*
* Old API for getting list of peer addresses. Does not work for 32-bit
* programs running on a 64-bit kernel
*/
static
int
sctp_getsockopt_peer_addrs_old
(
struct
sock
*
sk
,
int
len
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
struct
sctp_association
*
asoc
;
int
cnt
=
0
;
struct
sctp_getaddrs_old
getaddrs
;
struct
sctp_transport
*
from
;
void
__user
*
to
;
union
sctp_addr
temp
;
struct
sctp_sock
*
sp
=
sctp_sk
(
sk
);
int
addrlen
;
if
(
len
<
sizeof
(
struct
sctp_getaddrs_old
))
return
-
EINVAL
;
len
=
sizeof
(
struct
sctp_getaddrs_old
);
if
(
copy_from_user
(
&
getaddrs
,
optval
,
len
))
return
-
EFAULT
;
if
(
getaddrs
.
addr_num
<=
0
)
return
-
EINVAL
;
printk
(
KERN_WARNING
"SCTP: Use of SCTP_GET_PEER_ADDRS_OLD "
"socket option deprecated
\n
"
);
/* For UDP-style sockets, id specifies the association to query. */
asoc
=
sctp_id2assoc
(
sk
,
getaddrs
.
assoc_id
);
if
(
!
asoc
)
return
-
EINVAL
;
to
=
(
void
__user
*
)
getaddrs
.
addrs
;
list_for_each_entry
(
from
,
&
asoc
->
peer
.
transport_addr_list
,
transports
)
{
memcpy
(
&
temp
,
&
from
->
ipaddr
,
sizeof
(
temp
));
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sp
,
&
temp
);
addrlen
=
sctp_get_af_specific
(
sk
->
sk_family
)
->
sockaddr_len
;
if
(
copy_to_user
(
to
,
&
temp
,
addrlen
))
return
-
EFAULT
;
to
+=
addrlen
;
cnt
++
;
if
(
cnt
>=
getaddrs
.
addr_num
)
break
;
}
getaddrs
.
addr_num
=
cnt
;
if
(
put_user
(
len
,
optlen
))
return
-
EFAULT
;
if
(
copy_to_user
(
optval
,
&
getaddrs
,
len
))
return
-
EFAULT
;
return
0
;
}
static
int
sctp_getsockopt_peer_addrs
(
struct
sock
*
sk
,
int
len
,
static
int
sctp_getsockopt_peer_addrs
(
struct
sock
*
sk
,
int
len
,
char
__user
*
optval
,
int
__user
*
optlen
)
char
__user
*
optval
,
int
__user
*
optlen
)
...
@@ -4485,125 +4403,6 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
...
@@ -4485,125 +4403,6 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
return
0
;
return
0
;
}
}
static
int
sctp_getsockopt_local_addrs_num_old
(
struct
sock
*
sk
,
int
len
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
sctp_assoc_t
id
;
struct
sctp_bind_addr
*
bp
;
struct
sctp_association
*
asoc
;
struct
sctp_sockaddr_entry
*
addr
;
int
cnt
=
0
;
if
(
len
<
sizeof
(
sctp_assoc_t
))
return
-
EINVAL
;
if
(
copy_from_user
(
&
id
,
optval
,
sizeof
(
sctp_assoc_t
)))
return
-
EFAULT
;
printk
(
KERN_WARNING
"SCTP: Use of SCTP_GET_LOCAL_ADDRS_NUM_OLD "
"socket option deprecated
\n
"
);
/*
* For UDP-style sockets, id specifies the association to query.
* If the id field is set to the value '0' then the locally bound
* addresses are returned without regard to any particular
* association.
*/
if
(
0
==
id
)
{
bp
=
&
sctp_sk
(
sk
)
->
ep
->
base
.
bind_addr
;
}
else
{
asoc
=
sctp_id2assoc
(
sk
,
id
);
if
(
!
asoc
)
return
-
EINVAL
;
bp
=
&
asoc
->
base
.
bind_addr
;
}
/* If the endpoint is bound to 0.0.0.0 or ::0, count the valid
* addresses from the global local address list.
*/
if
(
sctp_list_single_entry
(
&
bp
->
address_list
))
{
addr
=
list_entry
(
bp
->
address_list
.
next
,
struct
sctp_sockaddr_entry
,
list
);
if
(
sctp_is_any
(
sk
,
&
addr
->
a
))
{
rcu_read_lock
();
list_for_each_entry_rcu
(
addr
,
&
sctp_local_addr_list
,
list
)
{
if
(
!
addr
->
valid
)
continue
;
if
((
PF_INET
==
sk
->
sk_family
)
&&
(
AF_INET6
==
addr
->
a
.
sa
.
sa_family
))
continue
;
if
((
PF_INET6
==
sk
->
sk_family
)
&&
inet_v6_ipv6only
(
sk
)
&&
(
AF_INET
==
addr
->
a
.
sa
.
sa_family
))
continue
;
cnt
++
;
}
rcu_read_unlock
();
}
else
{
cnt
=
1
;
}
goto
done
;
}
/* Protection on the bound address list is not needed,
* since in the socket option context we hold the socket lock,
* so there is no way that the bound address list can change.
*/
list_for_each_entry
(
addr
,
&
bp
->
address_list
,
list
)
{
cnt
++
;
}
done:
return
cnt
;
}
/* Helper function that copies local addresses to user and returns the number
* of addresses copied.
*/
static
int
sctp_copy_laddrs_old
(
struct
sock
*
sk
,
__u16
port
,
int
max_addrs
,
void
*
to
,
int
*
bytes_copied
)
{
struct
sctp_sockaddr_entry
*
addr
;
union
sctp_addr
temp
;
int
cnt
=
0
;
int
addrlen
;
rcu_read_lock
();
list_for_each_entry_rcu
(
addr
,
&
sctp_local_addr_list
,
list
)
{
if
(
!
addr
->
valid
)
continue
;
if
((
PF_INET
==
sk
->
sk_family
)
&&
(
AF_INET6
==
addr
->
a
.
sa
.
sa_family
))
continue
;
if
((
PF_INET6
==
sk
->
sk_family
)
&&
inet_v6_ipv6only
(
sk
)
&&
(
AF_INET
==
addr
->
a
.
sa
.
sa_family
))
continue
;
memcpy
(
&
temp
,
&
addr
->
a
,
sizeof
(
temp
));
if
(
!
temp
.
v4
.
sin_port
)
temp
.
v4
.
sin_port
=
htons
(
port
);
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sctp_sk
(
sk
),
&
temp
);
addrlen
=
sctp_get_af_specific
(
temp
.
sa
.
sa_family
)
->
sockaddr_len
;
memcpy
(
to
,
&
temp
,
addrlen
);
to
+=
addrlen
;
*
bytes_copied
+=
addrlen
;
cnt
++
;
if
(
cnt
>=
max_addrs
)
break
;
}
rcu_read_unlock
();
return
cnt
;
}
static
int
sctp_copy_laddrs
(
struct
sock
*
sk
,
__u16
port
,
void
*
to
,
static
int
sctp_copy_laddrs
(
struct
sock
*
sk
,
__u16
port
,
void
*
to
,
size_t
space_left
,
int
*
bytes_copied
)
size_t
space_left
,
int
*
bytes_copied
)
{
{
...
@@ -4647,112 +4446,6 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to,
...
@@ -4647,112 +4446,6 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to,
return
cnt
;
return
cnt
;
}
}
/* Old API for getting list of local addresses. Does not work for 32-bit
* programs running on a 64-bit kernel
*/
static
int
sctp_getsockopt_local_addrs_old
(
struct
sock
*
sk
,
int
len
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
struct
sctp_bind_addr
*
bp
;
struct
sctp_association
*
asoc
;
int
cnt
=
0
;
struct
sctp_getaddrs_old
getaddrs
;
struct
sctp_sockaddr_entry
*
addr
;
void
__user
*
to
;
union
sctp_addr
temp
;
struct
sctp_sock
*
sp
=
sctp_sk
(
sk
);
int
addrlen
;
int
err
=
0
;
void
*
addrs
;
void
*
buf
;
int
bytes_copied
=
0
;
if
(
len
<
sizeof
(
struct
sctp_getaddrs_old
))
return
-
EINVAL
;
len
=
sizeof
(
struct
sctp_getaddrs_old
);
if
(
copy_from_user
(
&
getaddrs
,
optval
,
len
))
return
-
EFAULT
;
if
(
getaddrs
.
addr_num
<=
0
||
getaddrs
.
addr_num
>=
(
INT_MAX
/
sizeof
(
union
sctp_addr
)))
return
-
EINVAL
;
printk
(
KERN_WARNING
"SCTP: Use of SCTP_GET_LOCAL_ADDRS_OLD "
"socket option deprecated
\n
"
);
/*
* For UDP-style sockets, id specifies the association to query.
* If the id field is set to the value '0' then the locally bound
* addresses are returned without regard to any particular
* association.
*/
if
(
0
==
getaddrs
.
assoc_id
)
{
bp
=
&
sctp_sk
(
sk
)
->
ep
->
base
.
bind_addr
;
}
else
{
asoc
=
sctp_id2assoc
(
sk
,
getaddrs
.
assoc_id
);
if
(
!
asoc
)
return
-
EINVAL
;
bp
=
&
asoc
->
base
.
bind_addr
;
}
to
=
getaddrs
.
addrs
;
/* Allocate space for a local instance of packed array to hold all
* the data. We store addresses here first and then put write them
* to the user in one shot.
*/
addrs
=
kmalloc
(
sizeof
(
union
sctp_addr
)
*
getaddrs
.
addr_num
,
GFP_KERNEL
);
if
(
!
addrs
)
return
-
ENOMEM
;
/* If the endpoint is bound to 0.0.0.0 or ::0, get the valid
* addresses from the global local address list.
*/
if
(
sctp_list_single_entry
(
&
bp
->
address_list
))
{
addr
=
list_entry
(
bp
->
address_list
.
next
,
struct
sctp_sockaddr_entry
,
list
);
if
(
sctp_is_any
(
sk
,
&
addr
->
a
))
{
cnt
=
sctp_copy_laddrs_old
(
sk
,
bp
->
port
,
getaddrs
.
addr_num
,
addrs
,
&
bytes_copied
);
goto
copy_getaddrs
;
}
}
buf
=
addrs
;
/* Protection on the bound address list is not needed since
* in the socket option context we hold a socket lock and
* thus the bound address list can't change.
*/
list_for_each_entry
(
addr
,
&
bp
->
address_list
,
list
)
{
memcpy
(
&
temp
,
&
addr
->
a
,
sizeof
(
temp
));
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sp
,
&
temp
);
addrlen
=
sctp_get_af_specific
(
temp
.
sa
.
sa_family
)
->
sockaddr_len
;
memcpy
(
buf
,
&
temp
,
addrlen
);
buf
+=
addrlen
;
bytes_copied
+=
addrlen
;
cnt
++
;
if
(
cnt
>=
getaddrs
.
addr_num
)
break
;
}
copy_getaddrs:
/* copy the entire address list into the user provided space */
if
(
copy_to_user
(
to
,
addrs
,
bytes_copied
))
{
err
=
-
EFAULT
;
goto
error
;
}
/* copy the leading structure back to user */
getaddrs
.
addr_num
=
cnt
;
if
(
copy_to_user
(
optval
,
&
getaddrs
,
len
))
err
=
-
EFAULT
;
error:
kfree
(
addrs
);
return
err
;
}
static
int
sctp_getsockopt_local_addrs
(
struct
sock
*
sk
,
int
len
,
static
int
sctp_getsockopt_local_addrs
(
struct
sock
*
sk
,
int
len
,
char
__user
*
optval
,
int
__user
*
optlen
)
char
__user
*
optval
,
int
__user
*
optlen
)
...
@@ -5603,22 +5296,6 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
...
@@ -5603,22 +5296,6 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
case
SCTP_INITMSG
:
case
SCTP_INITMSG
:
retval
=
sctp_getsockopt_initmsg
(
sk
,
len
,
optval
,
optlen
);
retval
=
sctp_getsockopt_initmsg
(
sk
,
len
,
optval
,
optlen
);
break
;
break
;
case
SCTP_GET_PEER_ADDRS_NUM_OLD
:
retval
=
sctp_getsockopt_peer_addrs_num_old
(
sk
,
len
,
optval
,
optlen
);
break
;
case
SCTP_GET_LOCAL_ADDRS_NUM_OLD
:
retval
=
sctp_getsockopt_local_addrs_num_old
(
sk
,
len
,
optval
,
optlen
);
break
;
case
SCTP_GET_PEER_ADDRS_OLD
:
retval
=
sctp_getsockopt_peer_addrs_old
(
sk
,
len
,
optval
,
optlen
);
break
;
case
SCTP_GET_LOCAL_ADDRS_OLD
:
retval
=
sctp_getsockopt_local_addrs_old
(
sk
,
len
,
optval
,
optlen
);
break
;
case
SCTP_GET_PEER_ADDRS
:
case
SCTP_GET_PEER_ADDRS
:
retval
=
sctp_getsockopt_peer_addrs
(
sk
,
len
,
optval
,
retval
=
sctp_getsockopt_peer_addrs
(
sk
,
len
,
optval
,
optlen
);
optlen
);
...
...
net/sctp/sysctl.c
View file @
5656b6ca
...
@@ -52,6 +52,7 @@ static int int_max = INT_MAX;
...
@@ -52,6 +52,7 @@ static int int_max = INT_MAX;
static
int
sack_timer_min
=
1
;
static
int
sack_timer_min
=
1
;
static
int
sack_timer_max
=
500
;
static
int
sack_timer_max
=
500
;
static
int
addr_scope_max
=
3
;
/* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
static
int
addr_scope_max
=
3
;
/* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
static
int
rwnd_scale_max
=
16
;
extern
int
sysctl_sctp_mem
[
3
];
extern
int
sysctl_sctp_mem
[
3
];
extern
int
sysctl_sctp_rmem
[
3
];
extern
int
sysctl_sctp_rmem
[
3
];
...
@@ -284,6 +285,18 @@ static ctl_table sctp_table[] = {
...
@@ -284,6 +285,18 @@ static ctl_table sctp_table[] = {
.
extra1
=
&
zero
,
.
extra1
=
&
zero
,
.
extra2
=
&
addr_scope_max
,
.
extra2
=
&
addr_scope_max
,
},
},
{
.
ctl_name
=
CTL_UNNUMBERED
,
.
procname
=
"rwnd_update_shift"
,
.
data
=
&
sctp_rwnd_upd_shift
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec_minmax
,
.
strategy
=
&
sysctl_intvec
,
.
extra1
=
&
one
,
.
extra2
=
&
rwnd_scale_max
,
},
{
.
ctl_name
=
0
}
{
.
ctl_name
=
0
}
};
};
...
...
net/sctp/transport.c
View file @
5656b6ca
...
@@ -83,7 +83,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
...
@@ -83,7 +83,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
peer
->
fast_recovery
=
0
;
peer
->
fast_recovery
=
0
;
peer
->
last_time_heard
=
jiffies
;
peer
->
last_time_heard
=
jiffies
;
peer
->
last_time_used
=
jiffies
;
peer
->
last_time_ecne_reduced
=
jiffies
;
peer
->
last_time_ecne_reduced
=
jiffies
;
peer
->
init_sent_count
=
0
;
peer
->
init_sent_count
=
0
;
...
@@ -565,8 +564,6 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
...
@@ -565,8 +564,6 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
* to be done every RTO interval, we do it every hearbeat
* to be done every RTO interval, we do it every hearbeat
* interval.
* interval.
*/
*/
if
(
time_after
(
jiffies
,
transport
->
last_time_used
+
transport
->
rto
))
transport
->
cwnd
=
max
(
transport
->
cwnd
/
2
,
transport
->
cwnd
=
max
(
transport
->
cwnd
/
2
,
4
*
transport
->
asoc
->
pathmtu
);
4
*
transport
->
asoc
->
pathmtu
);
break
;
break
;
...
@@ -579,6 +576,43 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
...
@@ -579,6 +576,43 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
transport
->
cwnd
,
transport
->
ssthresh
);
transport
->
cwnd
,
transport
->
ssthresh
);
}
}
/* Apply Max.Burst limit to the congestion window:
* sctpimpguide-05 2.14.2
* D) When the time comes for the sender to
* transmit new DATA chunks, the protocol parameter Max.Burst MUST
* first be applied to limit how many new DATA chunks may be sent.
* The limit is applied by adjusting cwnd as follows:
* if ((flightsize+ Max.Burst * MTU) < cwnd)
* cwnd = flightsize + Max.Burst * MTU
*/
void
sctp_transport_burst_limited
(
struct
sctp_transport
*
t
)
{
struct
sctp_association
*
asoc
=
t
->
asoc
;
u32
old_cwnd
=
t
->
cwnd
;
u32
max_burst_bytes
;
if
(
t
->
burst_limited
)
return
;
max_burst_bytes
=
t
->
flight_size
+
(
asoc
->
max_burst
*
asoc
->
pathmtu
);
if
(
max_burst_bytes
<
old_cwnd
)
{
t
->
cwnd
=
max_burst_bytes
;
t
->
burst_limited
=
old_cwnd
;
}
}
/* Restore the old cwnd congestion window, after the burst had it's
* desired effect.
*/
void
sctp_transport_burst_reset
(
struct
sctp_transport
*
t
)
{
if
(
t
->
burst_limited
)
{
t
->
cwnd
=
t
->
burst_limited
;
t
->
burst_limited
=
0
;
}
}
/* What is the next timeout value for this transport? */
/* What is the next timeout value for this transport? */
unsigned
long
sctp_transport_timeout
(
struct
sctp_transport
*
t
)
unsigned
long
sctp_transport_timeout
(
struct
sctp_transport
*
t
)
{
{
...
@@ -601,6 +635,7 @@ void sctp_transport_reset(struct sctp_transport *t)
...
@@ -601,6 +635,7 @@ void sctp_transport_reset(struct sctp_transport *t)
* (see Section 6.2.1)
* (see Section 6.2.1)
*/
*/
t
->
cwnd
=
min
(
4
*
asoc
->
pathmtu
,
max_t
(
__u32
,
2
*
asoc
->
pathmtu
,
4380
));
t
->
cwnd
=
min
(
4
*
asoc
->
pathmtu
,
max_t
(
__u32
,
2
*
asoc
->
pathmtu
,
4380
));
t
->
burst_limited
=
0
;
t
->
ssthresh
=
asoc
->
peer
.
i
.
a_rwnd
;
t
->
ssthresh
=
asoc
->
peer
.
i
.
a_rwnd
;
t
->
last_rto
=
t
->
rto
=
asoc
->
rto_initial
;
t
->
last_rto
=
t
->
rto
=
asoc
->
rto_initial
;
t
->
rtt
=
0
;
t
->
rtt
=
0
;
...
...
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