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
e3e9425c
Commit
e3e9425c
authored
Oct 25, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-lksctp.bkbits.net/lksctp-2.5.work
into nuts.davemloft.net:/disk1/BK/net-2.6
parents
bd32390f
30621d83
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
223 additions
and
28 deletions
+223
-28
include/linux/sctp.h
include/linux/sctp.h
+5
-1
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+1
-1
include/net/sctp/structs.h
include/net/sctp/structs.h
+6
-0
include/net/sctp/ulpevent.h
include/net/sctp/ulpevent.h
+3
-0
include/net/sctp/user.h
include/net/sctp/user.h
+1
-1
net/sctp/associola.c
net/sctp/associola.c
+7
-6
net/sctp/outqueue.c
net/sctp/outqueue.c
+12
-3
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+31
-0
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+59
-0
net/sctp/socket.c
net/sctp/socket.c
+48
-1
net/sctp/transport.c
net/sctp/transport.c
+14
-13
net/sctp/ulpevent.c
net/sctp/ulpevent.c
+36
-2
No files found.
include/linux/sctp.h
View file @
e3e9425c
...
@@ -281,7 +281,11 @@ typedef struct sctp_ecn_capable_param {
...
@@ -281,7 +281,11 @@ typedef struct sctp_ecn_capable_param {
sctp_paramhdr_t
param_hdr
;
sctp_paramhdr_t
param_hdr
;
}
__attribute__
((
packed
))
sctp_ecn_capable_param_t
;
}
__attribute__
((
packed
))
sctp_ecn_capable_param_t
;
/* ADDIP Section 3.2.6 Adaption Layer Indication */
typedef
struct
sctp_adaption_ind_param
{
struct
sctp_paramhdr
param_hdr
;
__u32
adaption_ind
;
}
__attribute__
((
packed
))
sctp_adaption_ind_param_t
;
/* RFC 2960. Section 3.3.3 Initiation Acknowledgement (INIT ACK) (2):
/* RFC 2960. Section 3.3.3 Initiation Acknowledgement (INIT ACK) (2):
* The INIT ACK chunk is used to acknowledge the initiation of an SCTP
* The INIT ACK chunk is used to acknowledge the initiation of an SCTP
...
...
include/net/sctp/sctp.h
View file @
e3e9425c
...
@@ -335,7 +335,7 @@ static inline void sctp_v6_exit(void) { return; }
...
@@ -335,7 +335,7 @@ static inline void sctp_v6_exit(void) { return; }
/* Map an association to an assoc_id. */
/* Map an association to an assoc_id. */
static
inline
sctp_assoc_t
sctp_assoc2id
(
const
struct
sctp_association
*
asoc
)
static
inline
sctp_assoc_t
sctp_assoc2id
(
const
struct
sctp_association
*
asoc
)
{
{
return
(
asoc
?
asoc
->
assoc_id
:
NULL
);
return
(
asoc
?
asoc
->
assoc_id
:
0
);
}
}
/* Look up the association by its id. */
/* Look up the association by its id. */
...
...
include/net/sctp/structs.h
View file @
e3e9425c
...
@@ -266,6 +266,7 @@ struct sctp_opt {
...
@@ -266,6 +266,7 @@ struct sctp_opt {
__u8
disable_fragments
;
__u8
disable_fragments
;
__u8
pd_mode
;
__u8
pd_mode
;
__u8
v4mapped
;
__u8
v4mapped
;
__u32
adaption_ind
;
/* Receive to here while partial delivery is in effect. */
/* Receive to here while partial delivery is in effect. */
struct
sk_buff_head
pd_lobby
;
struct
sk_buff_head
pd_lobby
;
...
@@ -323,6 +324,8 @@ struct sctp_cookie {
...
@@ -323,6 +324,8 @@ struct sctp_cookie {
__u8
prsctp_capable
;
__u8
prsctp_capable
;
__u32
adaption_ind
;
/* This is a shim for my peer's INIT packet, followed by
/* This is a shim for my peer's INIT packet, followed by
* a copy of the raw address list of the association.
* a copy of the raw address list of the association.
* The length of the raw address list is saved in the
* The length of the raw address list is saved in the
...
@@ -362,6 +365,7 @@ union sctp_params {
...
@@ -362,6 +365,7 @@ union sctp_params {
struct
sctp_ipv4addr_param
*
v4
;
struct
sctp_ipv4addr_param
*
v4
;
struct
sctp_ipv6addr_param
*
v6
;
struct
sctp_ipv6addr_param
*
v6
;
union
sctp_addr_param
*
addr
;
union
sctp_addr_param
*
addr
;
struct
sctp_adaption_ind_param
*
aind
;
};
};
/* RFC 2960. Section 3.3.5 Heartbeat.
/* RFC 2960. Section 3.3.5 Heartbeat.
...
@@ -1395,6 +1399,8 @@ struct sctp_association {
...
@@ -1395,6 +1399,8 @@ struct sctp_association {
__u8
asconf_capable
;
/* Does peer support ADDIP? */
__u8
asconf_capable
;
/* Does peer support ADDIP? */
__u8
prsctp_capable
;
/* Can peer do PR-SCTP? */
__u8
prsctp_capable
;
/* Can peer do PR-SCTP? */
__u32
adaption_ind
;
/* Adaption Code point. */
/* This mask is used to disable sending the ASCONF chunk
/* This mask is used to disable sending the ASCONF chunk
* with specified parameter to peer.
* with specified parameter to peer.
*/
*/
...
...
include/net/sctp/ulpevent.h
View file @
e3e9425c
...
@@ -121,6 +121,9 @@ struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
...
@@ -121,6 +121,9 @@ struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
__u32
indication
,
int
gfp
);
__u32
indication
,
int
gfp
);
struct
sctp_ulpevent
*
sctp_ulpevent_make_adaption_indication
(
const
struct
sctp_association
*
asoc
,
int
gfp
);
struct
sctp_ulpevent
*
sctp_ulpevent_make_rcvmsg
(
struct
sctp_association
*
asoc
,
struct
sctp_ulpevent
*
sctp_ulpevent_make_rcvmsg
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
chunk
,
struct
sctp_chunk
*
chunk
,
int
gfp
);
int
gfp
);
...
...
include/net/sctp/user.h
View file @
e3e9425c
...
@@ -55,7 +55,7 @@
...
@@ -55,7 +55,7 @@
#include <linux/types.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/socket.h>
typedef
void
*
sctp_assoc_t
;
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>.
...
...
net/sctp/associola.c
View file @
e3e9425c
...
@@ -271,7 +271,7 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
...
@@ -271,7 +271,7 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
asoc
->
need_ecne
=
0
;
asoc
->
need_ecne
=
0
;
asoc
->
assoc_id
=
(
sctp_assoc_t
)
-
1L
;
asoc
->
assoc_id
=
0
;
/* Assume that peer would support both address types unless we are
/* Assume that peer would support both address types unless we are
* told otherwise.
* told otherwise.
...
@@ -374,9 +374,9 @@ static void sctp_association_destroy(struct sctp_association *asoc)
...
@@ -374,9 +374,9 @@ static void sctp_association_destroy(struct sctp_association *asoc)
sctp_endpoint_put
(
asoc
->
ep
);
sctp_endpoint_put
(
asoc
->
ep
);
sock_put
(
asoc
->
base
.
sk
);
sock_put
(
asoc
->
base
.
sk
);
if
(
(
long
)
asoc
->
assoc_id
!=
-
1L
)
{
if
(
asoc
->
assoc_id
!=
0
)
{
spin_lock_bh
(
&
sctp_assocs_id_lock
);
spin_lock_bh
(
&
sctp_assocs_id_lock
);
idr_remove
(
&
sctp_assocs_id
,
(
long
)
asoc
->
assoc_id
);
idr_remove
(
&
sctp_assocs_id
,
asoc
->
assoc_id
);
spin_unlock_bh
(
&
sctp_assocs_id_lock
);
spin_unlock_bh
(
&
sctp_assocs_id_lock
);
}
}
...
@@ -482,14 +482,15 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
...
@@ -482,14 +482,15 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
/* 7.2.1 Slow-Start
/* 7.2.1 Slow-Start
*
*
* o The initial cwnd before data transmission or after a
* o The initial cwnd before DATA transmission or after a sufficiently
* sufficiently long idle period MUST be <= 2*MTU.
* long idle period MUST be set to
* min(4*MTU, max(2*MTU, 4380 bytes))
*
*
* o The initial value of ssthresh MAY be arbitrarily high
* o The initial value of ssthresh MAY be arbitrarily high
* (for example, implementations MAY use the size of the
* (for example, implementations MAY use the size of the
* receiver advertised window).
* receiver advertised window).
*/
*/
peer
->
cwnd
=
asoc
->
pmtu
*
2
;
peer
->
cwnd
=
min
(
4
*
asoc
->
pmtu
,
max_t
(
__u32
,
2
*
asoc
->
pmtu
,
4380
))
;
/* At this point, we may not have the receiver's advertised window,
/* At this point, we may not have the receiver's advertised window,
* so initialize ssthresh to the default value and it will be set
* so initialize ssthresh to the default value and it will be set
...
...
net/sctp/outqueue.c
View file @
e3e9425c
...
@@ -706,10 +706,19 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -706,10 +706,19 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
if
(
!
new_transport
)
{
if
(
!
new_transport
)
{
new_transport
=
asoc
->
peer
.
active_path
;
new_transport
=
asoc
->
peer
.
active_path
;
}
else
if
(
!
new_transport
->
active
)
{
}
else
if
(
!
new_transport
->
active
)
{
/* If the chunk is Heartbeat, send it to
/* If the chunk is Heartbeat or Heartbeat Ack,
* chunk->transport, even it's inactive.
* send it to chunk->transport, even if it's
* inactive.
*
* 3.3.6 Heartbeat Acknowledgement:
* ...
* A HEARTBEAT ACK is always sent to the source IP
* address of the IP datagram containing the
* HEARTBEAT chunk to which this ack is responding.
* ...
*/
*/
if
(
chunk
->
chunk_hdr
->
type
!=
SCTP_CID_HEARTBEAT
)
if
(
chunk
->
chunk_hdr
->
type
!=
SCTP_CID_HEARTBEAT
&&
chunk
->
chunk_hdr
->
type
!=
SCTP_CID_HEARTBEAT_ACK
)
new_transport
=
asoc
->
peer
.
active_path
;
new_transport
=
asoc
->
peer
.
active_path
;
}
}
...
...
net/sctp/sm_make_chunk.c
View file @
e3e9425c
...
@@ -171,6 +171,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
...
@@ -171,6 +171,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
struct
sctp_opt
*
sp
;
struct
sctp_opt
*
sp
;
sctp_supported_addrs_param_t
sat
;
sctp_supported_addrs_param_t
sat
;
__u16
types
[
2
];
__u16
types
[
2
];
sctp_adaption_ind_param_t
aiparam
;
/* RFC 2960 3.3.2 Initiation (INIT) (1)
/* RFC 2960 3.3.2 Initiation (INIT) (1)
*
*
...
@@ -196,6 +197,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
...
@@ -196,6 +197,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
chunksize
+=
sizeof
(
ecap_param
);
chunksize
+=
sizeof
(
ecap_param
);
if
(
sctp_prsctp_enable
)
if
(
sctp_prsctp_enable
)
chunksize
+=
sizeof
(
prsctp_param
);
chunksize
+=
sizeof
(
prsctp_param
);
chunksize
+=
sizeof
(
aiparam
);
chunksize
+=
vparam_len
;
chunksize
+=
vparam_len
;
/* RFC 2960 3.3.2 Initiation (INIT) (1)
/* RFC 2960 3.3.2 Initiation (INIT) (1)
...
@@ -234,6 +236,10 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
...
@@ -234,6 +236,10 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
sctp_addto_chunk
(
retval
,
sizeof
(
ecap_param
),
&
ecap_param
);
sctp_addto_chunk
(
retval
,
sizeof
(
ecap_param
),
&
ecap_param
);
if
(
sctp_prsctp_enable
)
if
(
sctp_prsctp_enable
)
sctp_addto_chunk
(
retval
,
sizeof
(
prsctp_param
),
&
prsctp_param
);
sctp_addto_chunk
(
retval
,
sizeof
(
prsctp_param
),
&
prsctp_param
);
aiparam
.
param_hdr
.
type
=
SCTP_PARAM_ADAPTION_LAYER_IND
;
aiparam
.
param_hdr
.
length
=
htons
(
sizeof
(
aiparam
));
aiparam
.
adaption_ind
=
htonl
(
sp
->
adaption_ind
);
sctp_addto_chunk
(
retval
,
sizeof
(
aiparam
),
&
aiparam
);
nodata:
nodata:
if
(
addrs
.
v
)
if
(
addrs
.
v
)
kfree
(
addrs
.
v
);
kfree
(
addrs
.
v
);
...
@@ -251,6 +257,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
...
@@ -251,6 +257,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
sctp_cookie_param_t
*
cookie
;
sctp_cookie_param_t
*
cookie
;
int
cookie_len
;
int
cookie_len
;
size_t
chunksize
;
size_t
chunksize
;
sctp_adaption_ind_param_t
aiparam
;
retval
=
NULL
;
retval
=
NULL
;
...
@@ -284,6 +291,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
...
@@ -284,6 +291,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
if
(
asoc
->
peer
.
prsctp_capable
)
if
(
asoc
->
peer
.
prsctp_capable
)
chunksize
+=
sizeof
(
prsctp_param
);
chunksize
+=
sizeof
(
prsctp_param
);
chunksize
+=
sizeof
(
aiparam
);
/* Now allocate and fill out the chunk. */
/* Now allocate and fill out the chunk. */
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_INIT_ACK
,
0
,
chunksize
);
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_INIT_ACK
,
0
,
chunksize
);
if
(
!
retval
)
if
(
!
retval
)
...
@@ -302,6 +311,11 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
...
@@ -302,6 +311,11 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
if
(
asoc
->
peer
.
prsctp_capable
)
if
(
asoc
->
peer
.
prsctp_capable
)
sctp_addto_chunk
(
retval
,
sizeof
(
prsctp_param
),
&
prsctp_param
);
sctp_addto_chunk
(
retval
,
sizeof
(
prsctp_param
),
&
prsctp_param
);
aiparam
.
param_hdr
.
type
=
SCTP_PARAM_ADAPTION_LAYER_IND
;
aiparam
.
param_hdr
.
length
=
htons
(
sizeof
(
aiparam
));
aiparam
.
adaption_ind
=
htonl
(
sctp_sk
(
asoc
->
base
.
sk
)
->
adaption_ind
);
sctp_addto_chunk
(
retval
,
sizeof
(
aiparam
),
&
aiparam
);
/* We need to remove the const qualifier at this point. */
/* We need to remove the const qualifier at this point. */
retval
->
asoc
=
(
struct
sctp_association
*
)
asoc
;
retval
->
asoc
=
(
struct
sctp_association
*
)
asoc
;
...
@@ -1297,6 +1311,9 @@ sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
...
@@ -1297,6 +1311,9 @@ sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
/* Remember PR-SCTP capability. */
/* Remember PR-SCTP capability. */
cookie
->
c
.
prsctp_capable
=
asoc
->
peer
.
prsctp_capable
;
cookie
->
c
.
prsctp_capable
=
asoc
->
peer
.
prsctp_capable
;
/* Save adaption indication in the cookie. */
cookie
->
c
.
adaption_ind
=
asoc
->
peer
.
adaption_ind
;
/* Set an expiration time for the cookie. */
/* Set an expiration time for the cookie. */
do_gettimeofday
(
&
cookie
->
c
.
expiration
);
do_gettimeofday
(
&
cookie
->
c
.
expiration
);
TIMEVAL_ADD
(
asoc
->
cookie_life
,
cookie
->
c
.
expiration
);
TIMEVAL_ADD
(
asoc
->
cookie_life
,
cookie
->
c
.
expiration
);
...
@@ -1455,6 +1472,7 @@ struct sctp_association *sctp_unpack_cookie(
...
@@ -1455,6 +1472,7 @@ struct sctp_association *sctp_unpack_cookie(
retval
->
addip_serial
=
retval
->
c
.
initial_tsn
;
retval
->
addip_serial
=
retval
->
c
.
initial_tsn
;
retval
->
adv_peer_ack_point
=
retval
->
ctsn_ack_point
;
retval
->
adv_peer_ack_point
=
retval
->
ctsn_ack_point
;
retval
->
peer
.
prsctp_capable
=
retval
->
c
.
prsctp_capable
;
retval
->
peer
.
prsctp_capable
=
retval
->
c
.
prsctp_capable
;
retval
->
peer
.
adaption_ind
=
retval
->
c
.
adaption_ind
;
/* The INIT stuff will be done by the side effects. */
/* The INIT stuff will be done by the side effects. */
return
retval
;
return
retval
;
...
@@ -1661,6 +1679,7 @@ static int sctp_verify_param(const struct sctp_association *asoc,
...
@@ -1661,6 +1679,7 @@ static int sctp_verify_param(const struct sctp_association *asoc,
case
SCTP_PARAM_HEARTBEAT_INFO
:
case
SCTP_PARAM_HEARTBEAT_INFO
:
case
SCTP_PARAM_UNRECOGNIZED_PARAMETERS
:
case
SCTP_PARAM_UNRECOGNIZED_PARAMETERS
:
case
SCTP_PARAM_ECN_CAPABLE
:
case
SCTP_PARAM_ECN_CAPABLE
:
case
SCTP_PARAM_ADAPTION_LAYER_IND
:
break
;
break
;
case
SCTP_PARAM_HOST_NAME_ADDRESS
:
case
SCTP_PARAM_HOST_NAME_ADDRESS
:
...
@@ -1989,6 +2008,10 @@ int sctp_process_param(struct sctp_association *asoc, union sctp_params param,
...
@@ -1989,6 +2008,10 @@ int sctp_process_param(struct sctp_association *asoc, union sctp_params param,
asoc
->
peer
.
ecn_capable
=
1
;
asoc
->
peer
.
ecn_capable
=
1
;
break
;
break
;
case
SCTP_PARAM_ADAPTION_LAYER_IND
:
asoc
->
peer
.
adaption_ind
=
param
.
aind
->
adaption_ind
;
break
;
case
SCTP_PARAM_FWD_TSN_SUPPORT
:
case
SCTP_PARAM_FWD_TSN_SUPPORT
:
if
(
sctp_prsctp_enable
)
{
if
(
sctp_prsctp_enable
)
{
asoc
->
peer
.
prsctp_capable
=
1
;
asoc
->
peer
.
prsctp_capable
=
1
;
...
@@ -2459,6 +2482,8 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
...
@@ -2459,6 +2482,8 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
union
sctp_addr
addr
;
union
sctp_addr
addr
;
struct
sctp_bind_addr
*
bp
=
&
asoc
->
base
.
bind_addr
;
struct
sctp_bind_addr
*
bp
=
&
asoc
->
base
.
bind_addr
;
union
sctp_addr_param
*
addr_param
;
union
sctp_addr_param
*
addr_param
;
struct
list_head
*
pos
;
struct
sctp_transport
*
transport
;
int
retval
=
0
;
int
retval
=
0
;
addr_param
=
(
union
sctp_addr_param
*
)
addr_param
=
(
union
sctp_addr_param
*
)
...
@@ -2482,6 +2507,12 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
...
@@ -2482,6 +2507,12 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
retval
=
sctp_del_bind_addr
(
bp
,
&
addr
);
retval
=
sctp_del_bind_addr
(
bp
,
&
addr
);
sctp_write_unlock
(
&
asoc
->
base
.
addr_lock
);
sctp_write_unlock
(
&
asoc
->
base
.
addr_lock
);
sctp_local_bh_enable
();
sctp_local_bh_enable
();
list_for_each
(
pos
,
&
asoc
->
peer
.
transport_addr_list
)
{
transport
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
sctp_transport_route
(
transport
,
NULL
,
sctp_sk
(
asoc
->
base
.
sk
));
}
break
;
break
;
default:
default:
break
;
break
;
...
...
net/sctp/sm_statefuns.c
View file @
e3e9425c
...
@@ -629,6 +629,21 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
...
@@ -629,6 +629,21 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
/* Sockets API Draft Section 5.3.1.6
* When a peer sends a Adaption Layer Indication parameter , SCTP
* delivers this notification to inform the application that of the
* peers requested adaption layer.
*/
if
(
new_asoc
->
peer
.
adaption_ind
)
{
ev
=
sctp_ulpevent_make_adaption_indication
(
new_asoc
,
GFP_ATOMIC
);
if
(
!
ev
)
goto
nomem_ev
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
}
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
nomem_ev:
nomem_ev:
...
@@ -713,6 +728,20 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
...
@@ -713,6 +728,20 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
/* Sockets API Draft Section 5.3.1.6
* When a peer sends a Adaption Layer Indication parameter , SCTP
* delivers this notification to inform the application that of the
* peers requested adaption layer.
*/
if
(
asoc
->
peer
.
adaption_ind
)
{
ev
=
sctp_ulpevent_make_adaption_indication
(
asoc
,
GFP_ATOMIC
);
if
(
!
ev
)
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
}
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
nomem:
nomem:
return
SCTP_DISPOSITION_NOMEM
;
return
SCTP_DISPOSITION_NOMEM
;
...
@@ -1532,6 +1561,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
...
@@ -1532,6 +1561,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
goto
nomem_ev
;
goto
nomem_ev
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
/* Sockets API Draft Section 5.3.1.6
* When a peer sends a Adaption Layer Indication parameter , SCTP
* delivers this notification to inform the application that of the
* peers requested adaption layer.
*/
if
(
asoc
->
peer
.
adaption_ind
)
{
ev
=
sctp_ulpevent_make_adaption_indication
(
asoc
,
GFP_ATOMIC
);
if
(
!
ev
)
goto
nomem_ev
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
}
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
nomem_ev:
nomem_ev:
...
@@ -1612,6 +1656,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,
...
@@ -1612,6 +1656,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,
goto
nomem
;
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
SCTP_ULPEVENT
(
ev
));
/* Sockets API Draft Section 5.3.1.6
* When a peer sends a Adaption Layer Indication parameter,
* SCTP delivers this notification to inform the application
* that of the peers requested adaption layer.
*/
if
(
new_asoc
->
peer
.
adaption_ind
)
{
ev
=
sctp_ulpevent_make_adaption_indication
(
new_asoc
,
GFP_ATOMIC
);
if
(
!
ev
)
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
}
}
}
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSMIT
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSMIT
,
SCTP_NULL
());
...
...
net/sctp/socket.c
View file @
e3e9425c
...
@@ -1063,7 +1063,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
...
@@ -1063,7 +1063,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
struct
sctp_sndrcvinfo
default_sinfo
=
{
0
};
struct
sctp_sndrcvinfo
default_sinfo
=
{
0
};
struct
sctp_sndrcvinfo
*
sinfo
;
struct
sctp_sndrcvinfo
*
sinfo
;
struct
sctp_initmsg
*
sinit
;
struct
sctp_initmsg
*
sinit
;
sctp_assoc_t
associd
=
NULL
;
sctp_assoc_t
associd
=
0
;
sctp_cmsgs_t
cmsgs
=
{
NULL
};
sctp_cmsgs_t
cmsgs
=
{
NULL
};
int
err
;
int
err
;
sctp_scope_t
scope
;
sctp_scope_t
scope
;
...
@@ -2120,6 +2120,20 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
...
@@ -2120,6 +2120,20 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
return
err
;
return
err
;
}
}
static
int
sctp_setsockopt_adaption_layer
(
struct
sock
*
sk
,
char
__user
*
optval
,
int
optlen
)
{
__u32
val
;
if
(
optlen
<
sizeof
(
__u32
))
return
-
EINVAL
;
if
(
copy_from_user
(
&
val
,
optval
,
sizeof
(
__u32
)))
return
-
EFAULT
;
sctp_sk
(
sk
)
->
adaption_ind
=
val
;
return
0
;
}
/* API 6.2 setsockopt(), getsockopt()
/* API 6.2 setsockopt(), getsockopt()
*
*
...
@@ -2219,6 +2233,10 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
...
@@ -2219,6 +2233,10 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
case
SCTP_MAXSEG
:
case
SCTP_MAXSEG
:
retval
=
sctp_setsockopt_maxseg
(
sk
,
optval
,
optlen
);
retval
=
sctp_setsockopt_maxseg
(
sk
,
optval
,
optlen
);
break
;
break
;
case
SCTP_ADAPTION_LAYER
:
retval
=
sctp_setsockopt_adaption_layer
(
sk
,
optval
,
optlen
);
break
;
default:
default:
retval
=
-
ENOPROTOOPT
;
retval
=
-
ENOPROTOOPT
;
break
;
break
;
...
@@ -2518,6 +2536,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
...
@@ -2518,6 +2536,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
/* User specified fragmentation limit. */
/* User specified fragmentation limit. */
sp
->
user_frag
=
0
;
sp
->
user_frag
=
0
;
sp
->
adaption_ind
=
0
;
sp
->
pf
=
sctp_get_pf_specific
(
sk
->
sk_family
);
sp
->
pf
=
sctp_get_pf_specific
(
sk
->
sk_family
);
/* Control variables for partial data delivery. */
/* Control variables for partial data delivery. */
...
@@ -3159,6 +3179,29 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
...
@@ -3159,6 +3179,29 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
return
0
;
return
0
;
}
}
/*
* 7.1.11 Set Adaption Layer Indicator (SCTP_ADAPTION_LAYER)
*
* Requests that the local endpoint set the specified Adaption Layer
* Indication parameter for all future INIT and INIT-ACK exchanges.
*/
static
int
sctp_getsockopt_adaption_layer
(
struct
sock
*
sk
,
int
len
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
__u32
val
;
if
(
len
<
sizeof
(
__u32
))
return
-
EINVAL
;
len
=
sizeof
(
__u32
);
val
=
sctp_sk
(
sk
)
->
adaption_ind
;
if
(
put_user
(
len
,
optlen
))
return
-
EFAULT
;
if
(
copy_to_user
(
optval
,
&
val
,
len
))
return
-
EFAULT
;
return
0
;
}
/*
/*
*
*
* 7.1.14 Set default send parameters (SCTP_DEFAULT_SEND_PARAM)
* 7.1.14 Set default send parameters (SCTP_DEFAULT_SEND_PARAM)
...
@@ -3515,6 +3558,10 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
...
@@ -3515,6 +3558,10 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
retval
=
sctp_getsockopt_peer_addr_info
(
sk
,
len
,
optval
,
retval
=
sctp_getsockopt_peer_addr_info
(
sk
,
len
,
optval
,
optlen
);
optlen
);
break
;
break
;
case
SCTP_ADAPTION_LAYER
:
retval
=
sctp_getsockopt_adaption_layer
(
sk
,
len
,
optval
,
optlen
);
break
;
default:
default:
retval
=
-
ENOPROTOOPT
;
retval
=
-
ENOPROTOOPT
;
break
;
break
;
...
...
net/sctp/transport.c
View file @
e3e9425c
...
@@ -421,15 +421,15 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
...
@@ -421,15 +421,15 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
{
{
switch
(
reason
)
{
switch
(
reason
)
{
case
SCTP_LOWER_CWND_T3_RTX
:
case
SCTP_LOWER_CWND_T3_RTX
:
/* RFC 2960 Section 7.2.3, sctpimpguide
-05 Section 2.9.2
/* RFC 2960 Section 7.2.3, sctpimpguide
* When the T3-rtx timer expires on an address, SCTP should
* When the T3-rtx timer expires on an address, SCTP should
* perform slow start by:
* perform slow start by:
* ssthresh = max(cwnd/2,
2
*MTU)
* ssthresh = max(cwnd/2,
4
*MTU)
* cwnd = 1*MTU
* cwnd = 1*MTU
* partial_bytes_acked = 0
* partial_bytes_acked = 0
*/
*/
transport
->
ssthresh
=
max
(
transport
->
cwnd
/
2
,
transport
->
ssthresh
=
max
(
transport
->
cwnd
/
2
,
2
*
transport
->
asoc
->
pmtu
);
4
*
transport
->
asoc
->
pmtu
);
transport
->
cwnd
=
transport
->
asoc
->
pmtu
;
transport
->
cwnd
=
transport
->
asoc
->
pmtu
;
break
;
break
;
...
@@ -439,15 +439,15 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
...
@@ -439,15 +439,15 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
* were last sent, according to the formula described in
* were last sent, according to the formula described in
* Section 7.2.3.
* Section 7.2.3.
*
*
* RFC 2960 7.2.3, sctpimpguide
-05 2.9.2 Upon detection of
* RFC 2960 7.2.3, sctpimpguide
Upon detection of packet
*
packet
losses from SACK (see Section 7.2.4), An endpoint
* losses from SACK (see Section 7.2.4), An endpoint
* should do the following:
* should do the following:
* ssthresh = max(cwnd/2,
2
*MTU)
* ssthresh = max(cwnd/2,
4
*MTU)
* cwnd = ssthresh
* cwnd = ssthresh
* partial_bytes_acked = 0
* partial_bytes_acked = 0
*/
*/
transport
->
ssthresh
=
max
(
transport
->
cwnd
/
2
,
transport
->
ssthresh
=
max
(
transport
->
cwnd
/
2
,
2
*
transport
->
asoc
->
pmtu
);
4
*
transport
->
asoc
->
pmtu
);
transport
->
cwnd
=
transport
->
ssthresh
;
transport
->
cwnd
=
transport
->
ssthresh
;
break
;
break
;
...
@@ -467,23 +467,24 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
...
@@ -467,23 +467,24 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
if
((
jiffies
-
transport
->
last_time_ecne_reduced
)
>
if
((
jiffies
-
transport
->
last_time_ecne_reduced
)
>
transport
->
rtt
)
{
transport
->
rtt
)
{
transport
->
ssthresh
=
max
(
transport
->
cwnd
/
2
,
transport
->
ssthresh
=
max
(
transport
->
cwnd
/
2
,
2
*
transport
->
asoc
->
pmtu
);
4
*
transport
->
asoc
->
pmtu
);
transport
->
cwnd
=
transport
->
ssthresh
;
transport
->
cwnd
=
transport
->
ssthresh
;
transport
->
last_time_ecne_reduced
=
jiffies
;
transport
->
last_time_ecne_reduced
=
jiffies
;
}
}
break
;
break
;
case
SCTP_LOWER_CWND_INACTIVE
:
case
SCTP_LOWER_CWND_INACTIVE
:
/* RFC 2960 Section 7.2.1, sctpimpguide
-05 Section 2.14.2
/* RFC 2960 Section 7.2.1, sctpimpguide
* When the
association
does not transmit data on a given
* When the
endpoint
does not transmit data on a given
* transport address
within an RTO, the cwnd of the transport
* transport address
, the cwnd of the transport address
*
address should be adjusted to 2*MTU
.
*
should be adjusted to max(cwnd/2, 4*MTU) per RTO
.
* NOTE: Although the draft recommends that this check needs
* NOTE: Although the draft recommends that this check needs
* 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
((
jiffies
-
transport
->
last_time_used
)
>
transport
->
rto
)
if
((
jiffies
-
transport
->
last_time_used
)
>
transport
->
rto
)
transport
->
cwnd
=
2
*
transport
->
asoc
->
pmtu
;
transport
->
cwnd
=
max
(
transport
->
cwnd
/
2
,
4
*
transport
->
asoc
->
pmtu
);
break
;
break
;
};
};
...
...
net/sctp/ulpevent.c
View file @
e3e9425c
...
@@ -562,7 +562,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
...
@@ -562,7 +562,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
struct
sctp_shutdown_event
*
sse
;
struct
sctp_shutdown_event
*
sse
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_
assoc_change
),
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_
shutdown_event
),
MSG_NOTIFICATION
,
gfp
);
MSG_NOTIFICATION
,
gfp
);
if
(
!
event
)
if
(
!
event
)
goto
fail
;
goto
fail
;
...
@@ -613,6 +613,40 @@ struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
...
@@ -613,6 +613,40 @@ struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
return
NULL
;
return
NULL
;
}
}
/* Create and initialize a SCTP_ADAPTION_INDICATION notification.
*
* Socket Extensions for SCTP
* 5.3.1.6 SCTP_ADAPTION_INDICATION
*/
struct
sctp_ulpevent
*
sctp_ulpevent_make_adaption_indication
(
const
struct
sctp_association
*
asoc
,
int
gfp
)
{
struct
sctp_ulpevent
*
event
;
struct
sctp_adaption_event
*
sai
;
struct
sk_buff
*
skb
;
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_adaption_event
),
MSG_NOTIFICATION
,
gfp
);
if
(
!
event
)
goto
fail
;
skb
=
sctp_event2skb
(
event
);
sai
=
(
struct
sctp_adaption_event
*
)
skb_put
(
skb
,
sizeof
(
struct
sctp_adaption_event
));
sai
->
sai_type
=
SCTP_ADAPTION_INDICATION
;
sai
->
sai_flags
=
0
;
sai
->
sai_length
=
sizeof
(
struct
sctp_adaption_event
);
sai
->
sai_adaption_ind
=
asoc
->
peer
.
adaption_ind
;
sctp_ulpevent_set_owner
(
event
,
asoc
);
sai
->
sai_assoc_id
=
sctp_assoc2id
(
asoc
);
return
event
;
fail:
return
NULL
;
}
/* A message has been received. Package this message as a notification
/* A message has been received. Package this message as a notification
* to pass it to the upper layers. Go ahead and calculate the sndrcvinfo
* to pass it to the upper layers. Go ahead and calculate the sndrcvinfo
* even if filtered out later.
* even if filtered out later.
...
@@ -689,7 +723,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
...
@@ -689,7 +723,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
struct
sctp_pdapi_event
*
pd
;
struct
sctp_pdapi_event
*
pd
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_
assoc_change
),
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_
pdapi_event
),
MSG_NOTIFICATION
,
gfp
);
MSG_NOTIFICATION
,
gfp
);
if
(
!
event
)
if
(
!
event
)
goto
fail
;
goto
fail
;
...
...
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