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
f6578e8d
Commit
f6578e8d
authored
Aug 06, 2003
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-lksctp.bkbits.net/lksctp-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents
aa2b4427
2d14da6a
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
421 additions
and
122 deletions
+421
-122
include/linux/sctp.h
include/linux/sctp.h
+44
-3
include/net/sctp/command.h
include/net/sctp/command.h
+1
-0
include/net/sctp/constants.h
include/net/sctp/constants.h
+6
-1
include/net/sctp/sm.h
include/net/sctp/sm.h
+12
-4
include/net/sctp/structs.h
include/net/sctp/structs.h
+15
-15
net/sctp/associola.c
net/sctp/associola.c
+4
-4
net/sctp/debug.c
net/sctp/debug.c
+1
-0
net/sctp/endpointola.c
net/sctp/endpointola.c
+1
-0
net/sctp/input.c
net/sctp/input.c
+6
-6
net/sctp/proc.c
net/sctp/proc.c
+2
-2
net/sctp/protocol.c
net/sctp/protocol.c
+57
-24
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+82
-0
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+28
-0
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+65
-0
net/sctp/sm_statetable.c
net/sctp/sm_statetable.c
+97
-0
net/sctp/socket.c
net/sctp/socket.c
+0
-63
No files found.
include/linux/sctp.h
View file @
f6578e8d
...
@@ -471,13 +471,54 @@ typedef struct sctp_cwr_chunk {
...
@@ -471,13 +471,54 @@ typedef struct sctp_cwr_chunk {
sctp_cwrhdr_t
cwr_hdr
;
sctp_cwrhdr_t
cwr_hdr
;
}
sctp_cwr_chunk_t
__attribute__
((
packed
));
}
sctp_cwr_chunk_t
__attribute__
((
packed
));
/* FIXME: Cleanup needs to continue below this line. */
/*
/*
* ADDIP Section 3.1 New Chunk Types
* ADDIP Section 3.1 New Chunk Types
*/
*/
/* ADDIP
* Section 3.1.1 Address Configuration Change Chunk (ASCONF)
*
* Serial Number: 32 bits (unsigned integer)
* This value represents a Serial Number for the ASCONF Chunk. The
* valid range of Serial Number is from 0 to 2^32-1.
* Serial Numbers wrap back to 0 after reaching 2^32 -1.
*
* Address Parameter: 8 or 20 bytes (depending on type)
* The address is an address of the sender of the ASCONF chunk,
* the address MUST be considered part of the association by the
* peer endpoint. This field may be used by the receiver of the
* ASCONF to help in finding the association. This parameter MUST
* be present in every ASCONF message i.e. it is a mandatory TLV
* parameter.
*
* ASCONF Parameter: TLV format
* Each Address configuration change is represented by a TLV
* parameter as defined in Section 3.2. One or more requests may
* be present in an ASCONF Chunk.
*
* Section 3.1.2 Address Configuration Acknowledgement Chunk (ASCONF-ACK)
*
* Serial Number: 32 bits (unsigned integer)
* This value represents the Serial Number for the received ASCONF
* Chunk that is acknowledged by this chunk. This value is copied
* from the received ASCONF Chunk.
*
* ASCONF Parameter Response: TLV format
* The ASCONF Parameter Response is used in the ASCONF-ACK to
* report status of ASCONF processing.
*/
typedef
struct
sctp_addiphdr
{
__u32
serial
;
__u8
params
[
0
];
}
sctp_addiphdr_t
__attribute__
((
packed
));
typedef
struct
sctp_addip_chunk
{
sctp_chunkhdr_t
chunk_hdr
;
sctp_addiphdr_t
addip_hdr
;
}
sctp_addip_chunk_t
__attribute__
((
packed
));
/* FIXME: Cleanup needs to continue below this line. */
/* ADDIP Section 3.1.1
/* ADDIP Section 3.1.1
*
*
...
...
include/net/sctp/command.h
View file @
f6578e8d
...
@@ -87,6 +87,7 @@ typedef enum {
...
@@ -87,6 +87,7 @@ typedef enum {
SCTP_CMD_RTO_PENDING
,
/* Set transport's rto_pending. */
SCTP_CMD_RTO_PENDING
,
/* Set transport's rto_pending. */
SCTP_CMD_PART_DELIVER
,
/* Partial data delivery considerations. */
SCTP_CMD_PART_DELIVER
,
/* Partial data delivery considerations. */
SCTP_CMD_RENEGE
,
/* Renege data on an association. */
SCTP_CMD_RENEGE
,
/* Renege data on an association. */
SCTP_CMD_SETUP_T4
,
/* ADDIP, setup T4 RTO timer parms. */
SCTP_CMD_LAST
SCTP_CMD_LAST
}
sctp_verb_t
;
}
sctp_verb_t
;
...
...
include/net/sctp/constants.h
View file @
f6578e8d
...
@@ -75,6 +75,9 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
...
@@ -75,6 +75,9 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
#define SCTP_NUM_BASE_CHUNK_TYPES (SCTP_CID_BASE_MAX + 1)
#define SCTP_NUM_BASE_CHUNK_TYPES (SCTP_CID_BASE_MAX + 1)
#define SCTP_NUM_CHUNK_TYPES (SCTP_NUM_BASE_CHUNKTYPES + 2)
#define SCTP_NUM_CHUNK_TYPES (SCTP_NUM_BASE_CHUNKTYPES + 2)
#define SCTP_CID_ADDIP_MIN SCTP_CID_ASCONF
#define SCTP_CID_ADDIP_MAX SCTP_CID_ASCONF_ACK
#define SCTP_NUM_ADDIP_CHUNK_TYPES 2
/* These are the different flavours of event. */
/* These are the different flavours of event. */
typedef
enum
{
typedef
enum
{
...
@@ -99,6 +102,7 @@ typedef enum {
...
@@ -99,6 +102,7 @@ typedef enum {
SCTP_EVENT_TIMEOUT_T1_INIT
,
SCTP_EVENT_TIMEOUT_T1_INIT
,
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
,
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
,
SCTP_EVENT_TIMEOUT_T3_RTX
,
SCTP_EVENT_TIMEOUT_T3_RTX
,
SCTP_EVENT_TIMEOUT_T4_RTO
,
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
,
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
,
SCTP_EVENT_TIMEOUT_HEARTBEAT
,
SCTP_EVENT_TIMEOUT_HEARTBEAT
,
SCTP_EVENT_TIMEOUT_SACK
,
SCTP_EVENT_TIMEOUT_SACK
,
...
@@ -122,9 +126,10 @@ typedef enum {
...
@@ -122,9 +126,10 @@ typedef enum {
SCTP_PRIMITIVE_ABORT
,
SCTP_PRIMITIVE_ABORT
,
SCTP_PRIMITIVE_SEND
,
SCTP_PRIMITIVE_SEND
,
SCTP_PRIMITIVE_REQUESTHEARTBEAT
,
SCTP_PRIMITIVE_REQUESTHEARTBEAT
,
SCTP_PRIMITIVE_ASCONF
,
}
sctp_event_primitive_t
;
}
sctp_event_primitive_t
;
#define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_
REQUESTHEARTBEAT
#define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_
ASCONF
#define SCTP_NUM_PRIMITIVE_TYPES (SCTP_EVENT_PRIMITIVE_MAX + 1)
#define SCTP_NUM_PRIMITIVE_TYPES (SCTP_EVENT_PRIMITIVE_MAX + 1)
/* We define here a utility type for manipulating subtypes.
/* We define here a utility type for manipulating subtypes.
...
...
include/net/sctp/sm.h
View file @
f6578e8d
...
@@ -117,6 +117,7 @@ sctp_state_fn_t sctp_sf_tabort_8_4_8;
...
@@ -117,6 +117,7 @@ sctp_state_fn_t sctp_sf_tabort_8_4_8;
sctp_state_fn_t
sctp_sf_operr_notify
;
sctp_state_fn_t
sctp_sf_operr_notify
;
sctp_state_fn_t
sctp_sf_t1_timer_expire
;
sctp_state_fn_t
sctp_sf_t1_timer_expire
;
sctp_state_fn_t
sctp_sf_t2_timer_expire
;
sctp_state_fn_t
sctp_sf_t2_timer_expire
;
sctp_state_fn_t
sctp_sf_t4_timer_expire
;
sctp_state_fn_t
sctp_sf_t5_timer_expire
;
sctp_state_fn_t
sctp_sf_t5_timer_expire
;
sctp_state_fn_t
sctp_sf_sendbeat_8_3
;
sctp_state_fn_t
sctp_sf_sendbeat_8_3
;
sctp_state_fn_t
sctp_sf_beat_8_3
;
sctp_state_fn_t
sctp_sf_beat_8_3
;
...
@@ -137,6 +138,8 @@ sctp_state_fn_t sctp_sf_unk_chunk;
...
@@ -137,6 +138,8 @@ sctp_state_fn_t sctp_sf_unk_chunk;
sctp_state_fn_t
sctp_sf_do_8_5_1_E_sa
;
sctp_state_fn_t
sctp_sf_do_8_5_1_E_sa
;
sctp_state_fn_t
sctp_sf_cookie_echoed_err
;
sctp_state_fn_t
sctp_sf_cookie_echoed_err
;
sctp_state_fn_t
sctp_sf_do_5_2_6_stale
;
sctp_state_fn_t
sctp_sf_do_5_2_6_stale
;
sctp_state_fn_t
sctp_sf_do_asconf
;
sctp_state_fn_t
sctp_sf_do_asconf_ack
;
/* Prototypes for primitive event state functions. */
/* Prototypes for primitive event state functions. */
sctp_state_fn_t
sctp_sf_do_prm_asoc
;
sctp_state_fn_t
sctp_sf_do_prm_asoc
;
...
@@ -154,6 +157,7 @@ sctp_state_fn_t sctp_sf_error_closed;
...
@@ -154,6 +157,7 @@ sctp_state_fn_t sctp_sf_error_closed;
sctp_state_fn_t
sctp_sf_error_shutdown
;
sctp_state_fn_t
sctp_sf_error_shutdown
;
sctp_state_fn_t
sctp_sf_ignore_primitive
;
sctp_state_fn_t
sctp_sf_ignore_primitive
;
sctp_state_fn_t
sctp_sf_do_prm_requestheartbeat
;
sctp_state_fn_t
sctp_sf_do_prm_requestheartbeat
;
sctp_state_fn_t
sctp_sf_do_prm_asconf
;
/* Prototypes for other event state functions. */
/* Prototypes for other event state functions. */
sctp_state_fn_t
sctp_sf_do_9_2_start_shutdown
;
sctp_state_fn_t
sctp_sf_do_9_2_start_shutdown
;
...
@@ -184,10 +188,6 @@ sctp_state_fn_t sctp_do_9_2_reshutack;
...
@@ -184,10 +188,6 @@ sctp_state_fn_t sctp_do_9_2_reshutack;
sctp_state_fn_t
sctp_do_8_3_hb_err
;
sctp_state_fn_t
sctp_do_8_3_hb_err
;
sctp_state_fn_t
sctp_heartoff
;
sctp_state_fn_t
sctp_heartoff
;
/* Prototypes for addip related state functions. Not in use. */
sctp_state_fn_t
sctp_addip_do_asconf
;
sctp_state_fn_t
sctp_addip_do_asconf_ack
;
/* Prototypes for utility support functions. */
/* Prototypes for utility support functions. */
__u8
sctp_get_chunk_type
(
struct
sctp_chunk
*
chunk
);
__u8
sctp_get_chunk_type
(
struct
sctp_chunk
*
chunk
);
const
sctp_sm_table_entry_t
*
sctp_sm_lookup_event
(
sctp_event_t
,
const
sctp_sm_table_entry_t
*
sctp_sm_lookup_event
(
sctp_event_t
,
...
@@ -260,6 +260,14 @@ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *,
...
@@ -260,6 +260,14 @@ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *,
__u16
cause_code
,
__u16
cause_code
,
const
void
*
payload
,
const
void
*
payload
,
size_t
paylen
);
size_t
paylen
);
struct
sctp_chunk
*
sctp_make_asconf
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
addr
,
int
vparam_len
);
struct
sctp_chunk
*
sctp_process_asconf
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
asconf
,
int
vparam_len
);
void
sctp_chunk_assign_tsn
(
struct
sctp_chunk
*
);
void
sctp_chunk_assign_tsn
(
struct
sctp_chunk
*
);
void
sctp_chunk_assign_ssn
(
struct
sctp_chunk
*
);
void
sctp_chunk_assign_ssn
(
struct
sctp_chunk
*
);
...
...
include/net/sctp/structs.h
View file @
f6578e8d
...
@@ -169,11 +169,11 @@ extern struct sctp_globals {
...
@@ -169,11 +169,11 @@ extern struct sctp_globals {
/* This is the hash of all endpoints. */
/* This is the hash of all endpoints. */
int
ep_hashsize
;
int
ep_hashsize
;
struct
sctp_hashbucket
*
ep_hash
bucket
;
struct
sctp_hashbucket
*
ep_hash
table
;
/* This is the hash of all associations. */
/* This is the hash of all associations. */
int
assoc_hashsize
;
int
assoc_hashsize
;
struct
sctp_hashbucket
*
assoc_hash
bucket
;
struct
sctp_hashbucket
*
assoc_hash
table
;
/* This is the sctp port control hash. */
/* This is the sctp port control hash. */
int
port_hashsize
;
int
port_hashsize
;
...
@@ -207,9 +207,9 @@ extern struct sctp_globals {
...
@@ -207,9 +207,9 @@ extern struct sctp_globals {
#define sctp_max_outstreams (sctp_globals.max_outstreams)
#define sctp_max_outstreams (sctp_globals.max_outstreams)
#define sctp_address_families (sctp_globals.address_families)
#define sctp_address_families (sctp_globals.address_families)
#define sctp_ep_hashsize (sctp_globals.ep_hashsize)
#define sctp_ep_hashsize (sctp_globals.ep_hashsize)
#define sctp_ep_hash
bucket (sctp_globals.ep_hashbucket
)
#define sctp_ep_hash
table (sctp_globals.ep_hashtable
)
#define sctp_assoc_hashsize (sctp_globals.assoc_hashsize)
#define sctp_assoc_hashsize (sctp_globals.assoc_hashsize)
#define sctp_assoc_hash
bucket (sctp_globals.assoc_hashbucket
)
#define sctp_assoc_hash
table (sctp_globals.assoc_hashtable
)
#define sctp_port_hashsize (sctp_globals.port_hashsize)
#define sctp_port_hashsize (sctp_globals.port_hashsize)
#define sctp_port_rover (sctp_globals.port_rover)
#define sctp_port_rover (sctp_globals.port_rover)
#define sctp_port_alloc_lock (sctp_globals.port_alloc_lock)
#define sctp_port_alloc_lock (sctp_globals.port_alloc_lock)
...
@@ -571,6 +571,7 @@ struct sctp_chunk {
...
@@ -571,6 +571,7 @@ struct sctp_chunk {
struct
sctp_ecnehdr
*
ecne_hdr
;
struct
sctp_ecnehdr
*
ecne_hdr
;
struct
sctp_cwrhdr
*
ecn_cwr_hdr
;
struct
sctp_cwrhdr
*
ecn_cwr_hdr
;
struct
sctp_errhdr
*
err_hdr
;
struct
sctp_errhdr
*
err_hdr
;
struct
sctp_addiphdr
*
addip_hdr
;
}
subh
;
}
subh
;
__u8
*
chunk_end
;
__u8
*
chunk_end
;
...
@@ -1385,8 +1386,10 @@ struct sctp_association {
...
@@ -1385,8 +1386,10 @@ struct sctp_association {
int
cookie_len
;
int
cookie_len
;
void
*
cookie
;
void
*
cookie
;
/* ADDIP Extention (ADDIP) --xguo */
/* ADDIP Section 4.2 Upon reception of an ASCONF Chunk.
/* <expected peer-serial-number> minus 1 (ADDIP sec. 4.2 C1) */
* C1) ... "Peer-Serial-Number'. This value MUST be initialized to the
* Initial TSN Value minus 1
*/
__u32
addip_serial
;
__u32
addip_serial
;
}
peer
;
}
peer
;
...
@@ -1623,12 +1626,12 @@ struct sctp_association {
...
@@ -1623,12 +1626,12 @@ struct sctp_association {
/* ADDIP Section 4.1 ASCONF Chunk Procedures
/* ADDIP Section 4.1 ASCONF Chunk Procedures
*
*
* A2) A serial number should be assigned to the Chunk. The
* A2) A serial number should be assigned to the Chunk. The
* serial number
should
be a monotonically increasing
* serial number
SHOULD
be a monotonically increasing
* number.
All serial numbers are defined to
be initialized at
* number.
The serial number SHOULD
be initialized at
* the start of the association to the same value as the
* the start of the association to the same value as the
* Initial TSN
.
* Initial TSN
and every time a new ASCONF chunk is created
*
*
it is incremented by one after assigning the serial number
*
[and]
*
to the newly created chunk.
*
*
* ADDIP
* ADDIP
* 3.1.1 Address/Stream Configuration Change Chunk (ASCONF)
* 3.1.1 Address/Stream Configuration Change Chunk (ASCONF)
...
@@ -1637,14 +1640,11 @@ struct sctp_association {
...
@@ -1637,14 +1640,11 @@ struct sctp_association {
*
*
* This value represents a Serial Number for the ASCONF
* This value represents a Serial Number for the ASCONF
* Chunk. The valid range of Serial Number is from 0 to
* Chunk. The valid range of Serial Number is from 0 to
* 4294967295 (2
**
32 - 1). Serial Numbers wrap back to 0
* 4294967295 (2
^
32 - 1). Serial Numbers wrap back to 0
* after reaching 4294967295.
* after reaching 4294967295.
*/
*/
__u32
addip_serial
;
__u32
addip_serial
;
/* Is the ADDIP extension enabled for this association? */
char
addip_enable
;
/* Need to send an ECNE Chunk? */
/* Need to send an ECNE Chunk? */
char
need_ecne
;
char
need_ecne
;
...
...
net/sctp/associola.c
View file @
f6578e8d
...
@@ -221,12 +221,14 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
...
@@ -221,12 +221,14 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
* remote endpoint it should do the following:
* remote endpoint it should do the following:
* ...
* ...
* A2) a serial number should be assigned to the chunk. The serial
* A2) a serial number should be assigned to the chunk. The serial
* number
should be a monotonically increasing number. All
serial
* number
SHOULD be a monotonically increasing number. The
serial
* numbers
are defined to
be initialized at the start of the
* numbers
SHOULD
be initialized at the start of the
* association to the same value as the initial TSN.
* association to the same value as the initial TSN.
*/
*/
asoc
->
addip_serial
=
asoc
->
c
.
initial_tsn
;
asoc
->
addip_serial
=
asoc
->
c
.
initial_tsn
;
skb_queue_head_init
(
&
asoc
->
addip_chunks
);
/* Make an empty list of remote transport addresses. */
/* Make an empty list of remote transport addresses. */
INIT_LIST_HEAD
(
&
asoc
->
peer
.
transport_addr_list
);
INIT_LIST_HEAD
(
&
asoc
->
peer
.
transport_addr_list
);
...
@@ -264,8 +266,6 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
...
@@ -264,8 +266,6 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
/* Set up the tsn tracking. */
/* Set up the tsn tracking. */
sctp_tsnmap_init
(
&
asoc
->
peer
.
tsn_map
,
SCTP_TSN_MAP_SIZE
,
0
);
sctp_tsnmap_init
(
&
asoc
->
peer
.
tsn_map
,
SCTP_TSN_MAP_SIZE
,
0
);
skb_queue_head_init
(
&
asoc
->
addip_chunks
);
asoc
->
need_ecne
=
0
;
asoc
->
need_ecne
=
0
;
asoc
->
eyecatcher
=
SCTP_ASSOC_EYECATCHER
;
asoc
->
eyecatcher
=
SCTP_ASSOC_EYECATCHER
;
...
...
net/sctp/debug.c
View file @
f6578e8d
...
@@ -185,6 +185,7 @@ static const char *sctp_timer_tbl[] = {
...
@@ -185,6 +185,7 @@ static const char *sctp_timer_tbl[] = {
"TIMEOUT_T1_INIT"
,
"TIMEOUT_T1_INIT"
,
"TIMEOUT_T2_SHUTDOWN"
,
"TIMEOUT_T2_SHUTDOWN"
,
"TIMEOUT_T3_RTX"
,
"TIMEOUT_T3_RTX"
,
"TIMEOUT_T4_RTO"
,
"TIMEOUT_T5_SHUTDOWN_GUARD"
,
"TIMEOUT_T5_SHUTDOWN_GUARD"
,
"TIMEOUT_HEARTBEAT"
,
"TIMEOUT_HEARTBEAT"
,
"TIMEOUT_SACK"
,
"TIMEOUT_SACK"
,
...
...
net/sctp/endpointola.c
View file @
f6578e8d
...
@@ -131,6 +131,7 @@ struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
...
@@ -131,6 +131,7 @@ struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
]
=
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
]
=
sp
->
rtoinfo
.
srto_initial
*
HZ
/
1000
;
sp
->
rtoinfo
.
srto_initial
*
HZ
/
1000
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T3_RTX
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T3_RTX
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T4_RTO
]
=
0
;
/* sctpimpguide-05 Section 2.12.2
/* sctpimpguide-05 Section 2.12.2
* If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the
* If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the
...
...
net/sctp/input.c
View file @
f6578e8d
...
@@ -528,7 +528,7 @@ void __sctp_hash_endpoint(struct sctp_endpoint *ep)
...
@@ -528,7 +528,7 @@ void __sctp_hash_endpoint(struct sctp_endpoint *ep)
epb
=
&
ep
->
base
;
epb
=
&
ep
->
base
;
epb
->
hashent
=
sctp_ep_hashfn
(
epb
->
bind_addr
.
port
);
epb
->
hashent
=
sctp_ep_hashfn
(
epb
->
bind_addr
.
port
);
head
=
&
sctp_ep_hash
bucket
[
epb
->
hashent
];
head
=
&
sctp_ep_hash
table
[
epb
->
hashent
];
sctp_write_lock
(
&
head
->
lock
);
sctp_write_lock
(
&
head
->
lock
);
epp
=
&
head
->
chain
;
epp
=
&
head
->
chain
;
...
@@ -558,7 +558,7 @@ void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
...
@@ -558,7 +558,7 @@ void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
epb
->
hashent
=
sctp_ep_hashfn
(
epb
->
bind_addr
.
port
);
epb
->
hashent
=
sctp_ep_hashfn
(
epb
->
bind_addr
.
port
);
head
=
&
sctp_ep_hash
bucket
[
epb
->
hashent
];
head
=
&
sctp_ep_hash
table
[
epb
->
hashent
];
sctp_write_lock
(
&
head
->
lock
);
sctp_write_lock
(
&
head
->
lock
);
...
@@ -589,7 +589,7 @@ struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr)
...
@@ -589,7 +589,7 @@ struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr)
int
hash
;
int
hash
;
hash
=
sctp_ep_hashfn
(
laddr
->
v4
.
sin_port
);
hash
=
sctp_ep_hashfn
(
laddr
->
v4
.
sin_port
);
head
=
&
sctp_ep_hash
bucket
[
hash
];
head
=
&
sctp_ep_hash
table
[
hash
];
read_lock
(
&
head
->
lock
);
read_lock
(
&
head
->
lock
);
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
ep
=
sctp_ep
(
epb
);
ep
=
sctp_ep
(
epb
);
...
@@ -627,7 +627,7 @@ void __sctp_hash_established(struct sctp_association *asoc)
...
@@ -627,7 +627,7 @@ void __sctp_hash_established(struct sctp_association *asoc)
/* Calculate which chain this entry will belong to. */
/* Calculate which chain this entry will belong to. */
epb
->
hashent
=
sctp_assoc_hashfn
(
epb
->
bind_addr
.
port
,
asoc
->
peer
.
port
);
epb
->
hashent
=
sctp_assoc_hashfn
(
epb
->
bind_addr
.
port
,
asoc
->
peer
.
port
);
head
=
&
sctp_assoc_hash
bucket
[
epb
->
hashent
];
head
=
&
sctp_assoc_hash
table
[
epb
->
hashent
];
sctp_write_lock
(
&
head
->
lock
);
sctp_write_lock
(
&
head
->
lock
);
epp
=
&
head
->
chain
;
epp
=
&
head
->
chain
;
...
@@ -658,7 +658,7 @@ void __sctp_unhash_established(struct sctp_association *asoc)
...
@@ -658,7 +658,7 @@ void __sctp_unhash_established(struct sctp_association *asoc)
epb
->
hashent
=
sctp_assoc_hashfn
(
epb
->
bind_addr
.
port
,
epb
->
hashent
=
sctp_assoc_hashfn
(
epb
->
bind_addr
.
port
,
asoc
->
peer
.
port
);
asoc
->
peer
.
port
);
head
=
&
sctp_assoc_hash
bucket
[
epb
->
hashent
];
head
=
&
sctp_assoc_hash
table
[
epb
->
hashent
];
sctp_write_lock
(
&
head
->
lock
);
sctp_write_lock
(
&
head
->
lock
);
...
@@ -688,7 +688,7 @@ struct sctp_association *__sctp_lookup_association(
...
@@ -688,7 +688,7 @@ struct sctp_association *__sctp_lookup_association(
* have wildcards anyways.
* have wildcards anyways.
*/
*/
hash
=
sctp_assoc_hashfn
(
local
->
v4
.
sin_port
,
peer
->
v4
.
sin_port
);
hash
=
sctp_assoc_hashfn
(
local
->
v4
.
sin_port
,
peer
->
v4
.
sin_port
);
head
=
&
sctp_assoc_hash
bucket
[
hash
];
head
=
&
sctp_assoc_hash
table
[
hash
];
read_lock
(
&
head
->
lock
);
read_lock
(
&
head
->
lock
);
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
asoc
=
sctp_assoc
(
epb
);
asoc
=
sctp_assoc
(
epb
);
...
...
net/sctp/proc.c
View file @
f6578e8d
...
@@ -172,7 +172,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
...
@@ -172,7 +172,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
seq_printf
(
seq
,
" ENDPT SOCK STY SST HBKT LPORT LADDRS
\n
"
);
seq_printf
(
seq
,
" ENDPT SOCK STY SST HBKT LPORT LADDRS
\n
"
);
for
(
hash
=
0
;
hash
<
sctp_ep_hashsize
;
hash
++
)
{
for
(
hash
=
0
;
hash
<
sctp_ep_hashsize
;
hash
++
)
{
head
=
&
sctp_ep_hash
bucket
[
hash
];
head
=
&
sctp_ep_hash
table
[
hash
];
read_lock
(
&
head
->
lock
);
read_lock
(
&
head
->
lock
);
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
ep
=
sctp_ep
(
epb
);
ep
=
sctp_ep
(
epb
);
...
@@ -234,7 +234,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
...
@@ -234,7 +234,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
seq_printf
(
seq
,
" ASSOC SOCK STY SST ST HBKT LPORT RPORT "
seq_printf
(
seq
,
" ASSOC SOCK STY SST ST HBKT LPORT RPORT "
"LADDRS <-> RADDRS
\n
"
);
"LADDRS <-> RADDRS
\n
"
);
for
(
hash
=
0
;
hash
<
sctp_assoc_hashsize
;
hash
++
)
{
for
(
hash
=
0
;
hash
<
sctp_assoc_hashsize
;
hash
++
)
{
head
=
&
sctp_assoc_hash
bucket
[
hash
];
head
=
&
sctp_assoc_hash
table
[
hash
];
read_lock
(
&
head
->
lock
);
read_lock
(
&
head
->
lock
);
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
assoc
=
sctp_assoc
(
epb
);
assoc
=
sctp_assoc
(
epb
);
...
...
net/sctp/protocol.c
View file @
f6578e8d
...
@@ -934,6 +934,8 @@ __init int sctp_init(void)
...
@@ -934,6 +934,8 @@ __init int sctp_init(void)
{
{
int
i
;
int
i
;
int
status
=
0
;
int
status
=
0
;
unsigned
long
goal
;
int
order
;
/* SCTP_DEBUG sanity check. */
/* SCTP_DEBUG sanity check. */
if
(
!
sctp_sanity_check
())
if
(
!
sctp_sanity_check
())
...
@@ -1017,52 +1019,75 @@ __init int sctp_init(void)
...
@@ -1017,52 +1019,75 @@ __init int sctp_init(void)
sctp_max_instreams
=
SCTP_DEFAULT_INSTREAMS
;
sctp_max_instreams
=
SCTP_DEFAULT_INSTREAMS
;
sctp_max_outstreams
=
SCTP_DEFAULT_OUTSTREAMS
;
sctp_max_outstreams
=
SCTP_DEFAULT_OUTSTREAMS
;
/* Allocate and initialize the association hash table. */
/* Size and allocate the association hash table.
sctp_assoc_hashsize
=
4096
;
* The methodology is similar to that of the tcp hash tables.
sctp_assoc_hashbucket
=
(
struct
sctp_hashbucket
*
)
*/
kmalloc
(
4096
*
sizeof
(
struct
sctp_hashbucket
),
GFP_KERNEL
);
if
(
num_physpages
>=
(
128
*
1024
))
if
(
!
sctp_assoc_hashbucket
)
{
goal
=
num_physpages
>>
(
22
-
PAGE_SHIFT
);
else
goal
=
num_physpages
>>
(
24
-
PAGE_SHIFT
);
for
(
order
=
0
;
(
1UL
<<
order
)
<
goal
;
order
++
)
;
do
{
sctp_assoc_hashsize
=
(
1UL
<<
order
)
*
PAGE_SIZE
/
sizeof
(
struct
sctp_hashbucket
);
if
((
sctp_assoc_hashsize
>
(
64
*
1024
))
&&
order
>
0
)
continue
;
sctp_assoc_hashtable
=
(
struct
sctp_hashbucket
*
)
__get_free_pages
(
GFP_ATOMIC
,
order
);
}
while
(
!
sctp_assoc_hashtable
&&
--
order
>
0
);
if
(
!
sctp_assoc_hashtable
)
{
printk
(
KERN_ERR
"SCTP: Failed association hash alloc.
\n
"
);
printk
(
KERN_ERR
"SCTP: Failed association hash alloc.
\n
"
);
status
=
-
ENOMEM
;
status
=
-
ENOMEM
;
goto
err_ahash_alloc
;
goto
err_ahash_alloc
;
}
}
for
(
i
=
0
;
i
<
sctp_assoc_hashsize
;
i
++
)
{
for
(
i
=
0
;
i
<
sctp_assoc_hashsize
;
i
++
)
{
sctp_assoc_hash
bucket
[
i
].
lock
=
RW_LOCK_UNLOCKED
;
sctp_assoc_hash
table
[
i
].
lock
=
RW_LOCK_UNLOCKED
;
sctp_assoc_hash
bucket
[
i
].
chain
=
NULL
;
sctp_assoc_hash
table
[
i
].
chain
=
NULL
;
}
}
/* Allocate and initialize the endpoint hash table. */
/* Allocate and initialize the endpoint hash table. */
sctp_ep_hashsize
=
64
;
sctp_ep_hashsize
=
64
;
sctp_ep_hash
bucket
=
(
struct
sctp_hashbucket
*
)
sctp_ep_hash
table
=
(
struct
sctp_hashbucket
*
)
kmalloc
(
64
*
sizeof
(
struct
sctp_hashbucket
),
GFP_KERNEL
);
kmalloc
(
64
*
sizeof
(
struct
sctp_hashbucket
),
GFP_KERNEL
);
if
(
!
sctp_ep_hash
bucket
)
{
if
(
!
sctp_ep_hash
table
)
{
printk
(
KERN_ERR
"SCTP: Failed endpoint_hash alloc.
\n
"
);
printk
(
KERN_ERR
"SCTP: Failed endpoint_hash alloc.
\n
"
);
status
=
-
ENOMEM
;
status
=
-
ENOMEM
;
goto
err_ehash_alloc
;
goto
err_ehash_alloc
;
}
}
for
(
i
=
0
;
i
<
sctp_ep_hashsize
;
i
++
)
{
for
(
i
=
0
;
i
<
sctp_ep_hashsize
;
i
++
)
{
sctp_ep_hash
bucket
[
i
].
lock
=
RW_LOCK_UNLOCKED
;
sctp_ep_hash
table
[
i
].
lock
=
RW_LOCK_UNLOCKED
;
sctp_ep_hash
bucket
[
i
].
chain
=
NULL
;
sctp_ep_hash
table
[
i
].
chain
=
NULL
;
}
}
/* Allocate and initialize the SCTP port hash table. */
/* Allocate and initialize the SCTP port hash table. */
sctp_port_hashsize
=
4096
;
do
{
sctp_port_hashtable
=
(
struct
sctp_bind_hashbucket
*
)
sctp_port_hashsize
=
(
1UL
<<
order
)
*
PAGE_SIZE
/
kmalloc
(
4096
*
sizeof
(
struct
sctp_bind_hashbucket
),
GFP_KERNEL
);
sizeof
(
struct
sctp_bind_hashbucket
);
if
((
sctp_port_hashsize
>
(
64
*
1024
))
&&
order
>
0
)
continue
;
sctp_port_hashtable
=
(
struct
sctp_bind_hashbucket
*
)
__get_free_pages
(
GFP_ATOMIC
,
order
);
}
while
(
!
sctp_port_hashtable
&&
--
order
>
0
);
if
(
!
sctp_port_hashtable
)
{
if
(
!
sctp_port_hashtable
)
{
printk
(
KERN_ERR
"SCTP: Failed bind hash alloc."
);
printk
(
KERN_ERR
"SCTP: Failed bind hash alloc."
);
status
=
-
ENOMEM
;
status
=
-
ENOMEM
;
goto
err_bhash_alloc
;
goto
err_bhash_alloc
;
}
}
sctp_port_alloc_lock
=
SPIN_LOCK_UNLOCKED
;
sctp_port_rover
=
sysctl_local_port_range
[
0
]
-
1
;
for
(
i
=
0
;
i
<
sctp_port_hashsize
;
i
++
)
{
for
(
i
=
0
;
i
<
sctp_port_hashsize
;
i
++
)
{
sctp_port_hashtable
[
i
].
lock
=
SPIN_LOCK_UNLOCKED
;
sctp_port_hashtable
[
i
].
lock
=
SPIN_LOCK_UNLOCKED
;
sctp_port_hashtable
[
i
].
chain
=
NULL
;
sctp_port_hashtable
[
i
].
chain
=
NULL
;
}
}
sctp_port_alloc_lock
=
SPIN_LOCK_UNLOCKED
;
sctp_port_rover
=
sysctl_local_port_range
[
0
]
-
1
;
printk
(
KERN_INFO
"SCTP: Hash tables configured "
"(established %d bind %d)
\n
"
,
sctp_assoc_hashsize
,
sctp_port_hashsize
);
sctp_sysctl_register
();
sctp_sysctl_register
();
INIT_LIST_HEAD
(
&
sctp_address_families
);
INIT_LIST_HEAD
(
&
sctp_address_families
);
...
@@ -1096,11 +1121,15 @@ __init int sctp_init(void)
...
@@ -1096,11 +1121,15 @@ __init int sctp_init(void)
err_v6_init:
err_v6_init:
sctp_sysctl_unregister
();
sctp_sysctl_unregister
();
list_del
(
&
sctp_ipv4_specific
.
list
);
list_del
(
&
sctp_ipv4_specific
.
list
);
kfree
(
sctp_port_hashtable
);
free_pages
((
unsigned
long
)
sctp_port_hashtable
,
get_order
(
sctp_port_hashsize
*
sizeof
(
struct
sctp_bind_hashbucket
)));
err_bhash_alloc:
err_bhash_alloc:
kfree
(
sctp_ep_hash
bucket
);
kfree
(
sctp_ep_hash
table
);
err_ehash_alloc:
err_ehash_alloc:
kfree
(
sctp_assoc_hashbucket
);
free_pages
((
unsigned
long
)
sctp_assoc_hashtable
,
get_order
(
sctp_assoc_hashsize
*
sizeof
(
struct
sctp_hashbucket
)));
err_ahash_alloc:
err_ahash_alloc:
sctp_dbg_objcnt_exit
();
sctp_dbg_objcnt_exit
();
sctp_proc_exit
();
sctp_proc_exit
();
...
@@ -1136,9 +1165,13 @@ __exit void sctp_exit(void)
...
@@ -1136,9 +1165,13 @@ __exit void sctp_exit(void)
sctp_sysctl_unregister
();
sctp_sysctl_unregister
();
list_del
(
&
sctp_ipv4_specific
.
list
);
list_del
(
&
sctp_ipv4_specific
.
list
);
kfree
(
sctp_assoc_hashbucket
);
free_pages
((
unsigned
long
)
sctp_assoc_hashtable
,
kfree
(
sctp_ep_hashbucket
);
get_order
(
sctp_assoc_hashsize
*
kfree
(
sctp_port_hashtable
);
sizeof
(
struct
sctp_hashbucket
)));
kfree
(
sctp_ep_hashtable
);
free_pages
((
unsigned
long
)
sctp_port_hashtable
,
get_order
(
sctp_port_hashsize
*
sizeof
(
struct
sctp_bind_hashbucket
)));
kmem_cache_destroy
(
sctp_chunk_cachep
);
kmem_cache_destroy
(
sctp_chunk_cachep
);
kmem_cache_destroy
(
sctp_bucket_cachep
);
kmem_cache_destroy
(
sctp_bucket_cachep
);
...
...
net/sctp/sm_make_chunk.c
View file @
f6578e8d
...
@@ -2088,3 +2088,85 @@ int sockaddr2sctp_addr(const union sctp_addr *sa, union sctp_addr_param *p)
...
@@ -2088,3 +2088,85 @@ int sockaddr2sctp_addr(const union sctp_addr *sa, union sctp_addr_param *p)
return
len
;
return
len
;
}
}
/*
* ADDIP 3.1.1 Address Configuration Change Chunk (ASCONF)
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type = 0xC1 | Chunk Flags | Chunk Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Serial Number |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Address Parameter |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ASCONF Parameter #1 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* \ \
* / .... /
* \ \
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ASCONF Parameter #N |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Address Parameter and other parameter will not be wrapped in this function
*/
struct
sctp_chunk
*
sctp_make_asconf
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
addr
,
int
vparam_len
)
{
sctp_addiphdr_t
asconf
;
struct
sctp_chunk
*
retval
;
int
length
=
sizeof
(
asconf
)
+
vparam_len
;
union
sctp_params
addrparam
;
int
addrlen
;
addrlen
=
sockaddr2sctp_addr
(
addr
,
(
union
sctp_addr_param
*
)
&
addrparam
);
if
(
!
addrlen
)
return
NULL
;
length
+=
addrlen
;
/* Create the chunk. */
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_ASCONF
,
0
,
length
);
if
(
!
retval
)
return
NULL
;
asconf
.
serial
=
asoc
->
addip_serial
++
;
retval
->
subh
.
addip_hdr
=
sctp_addto_chunk
(
retval
,
sizeof
(
asconf
),
&
asconf
);
retval
->
param_hdr
.
v
=
sctp_addto_chunk
(
retval
,
addrlen
,
&
addr
);
return
retval
;
}
/*
* Unpack the parameters in an ASCONF chunk into an association and
* generate ASCONF-ACK chunk.
*
* ADDIP 3.1.2 Address Configuration Acknowledgement Chunk (ASCONF-ACK)
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type = 0x80 | Chunk Flags | Chunk Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Serial Number |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ASCONF Parameter Response#1 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* \ \
* / .... /
* \ \
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ASCONF Parameter Response#N |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* All the parameter respoinces will be added in this function.
*/
struct
sctp_chunk
*
sctp_process_asconf
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
asconf
,
int
vparam_len
)
{
// FIXME: process asconf chunk
return
NULL
;
}
net/sctp/sm_sideeffect.c
View file @
f6578e8d
...
@@ -294,6 +294,12 @@ void sctp_generate_t2_shutdown_event(unsigned long data)
...
@@ -294,6 +294,12 @@ void sctp_generate_t2_shutdown_event(unsigned long data)
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
);
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
);
}
}
void
sctp_generate_t4_rto_event
(
unsigned
long
data
)
{
struct
sctp_association
*
asoc
=
(
struct
sctp_association
*
)
data
;
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T4_RTO
);
}
void
sctp_generate_t5_shutdown_guard_event
(
unsigned
long
data
)
void
sctp_generate_t5_shutdown_guard_event
(
unsigned
long
data
)
{
{
struct
sctp_association
*
asoc
=
(
struct
sctp_association
*
)
data
;
struct
sctp_association
*
asoc
=
(
struct
sctp_association
*
)
data
;
...
@@ -359,6 +365,7 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
...
@@ -359,6 +365,7 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
sctp_generate_t1_init_event
,
sctp_generate_t1_init_event
,
sctp_generate_t2_shutdown_event
,
sctp_generate_t2_shutdown_event
,
NULL
,
NULL
,
sctp_generate_t4_rto_event
,
sctp_generate_t5_shutdown_guard_event
,
sctp_generate_t5_shutdown_guard_event
,
sctp_generate_heartbeat_event
,
sctp_generate_heartbeat_event
,
sctp_generate_sack_event
,
sctp_generate_sack_event
,
...
@@ -666,6 +673,23 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds,
...
@@ -666,6 +673,23 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds,
sctp_association_free
(
asoc
);
sctp_association_free
(
asoc
);
}
}
/*
* ADDIP Section 4.1 ASCONF Chunk Procedures
* A4) Start a T-4 RTO timer, using the RTO value of the selected
* destination address (normally the primary path; see RFC2960
* section 6.4 for details).
*/
static
void
sctp_cmd_setup_t4
(
sctp_cmd_seq_t
*
cmds
,
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
chunk
)
{
struct
sctp_transport
*
t
;
t
=
asoc
->
peer
.
primary_path
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T4_RTO
]
=
t
->
rto
;
chunk
->
transport
=
t
;
}
/* These three macros allow us to pull the debugging code out of the
/* These three macros allow us to pull the debugging code out of the
* main flow of sctp_do_sm() to keep attention focused on the real
* main flow of sctp_do_sm() to keep attention focused on the real
* functionality there.
* functionality there.
...
@@ -1177,6 +1201,10 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
...
@@ -1177,6 +1201,10 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
GFP_ATOMIC
);
GFP_ATOMIC
);
break
;
break
;
case
SCTP_CMD_SETUP_T4
:
sctp_cmd_setup_t4
(
commands
,
asoc
,
cmd
->
obj
.
ptr
);
break
;
default:
default:
printk
(
KERN_WARNING
"Impossible command: %u, %p
\n
"
,
printk
(
KERN_WARNING
"Impossible command: %u, %p
\n
"
,
cmd
->
verb
,
cmd
->
obj
.
ptr
);
cmd
->
verb
,
cmd
->
obj
.
ptr
);
...
...
net/sctp/sm_statefuns.c
View file @
f6578e8d
...
@@ -3062,6 +3062,36 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
...
@@ -3062,6 +3062,36 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
return
sctp_sf_shut_8_4_5
(
ep
,
NULL
,
type
,
arg
,
commands
);
return
sctp_sf_shut_8_4_5
(
ep
,
NULL
,
type
,
arg
,
commands
);
}
}
/*
* ADDIP Section 4.2 Upon reception of an ASCONF Chunk
* When an endpoint receive an ASCONF Chunk from the remote peer
* special procedures MAY be needed to identify the association the
* ASCONF Chunk is associated with. To properly find the association
* the following procedures should be L1 to L4 and C1 to C5
*/
sctp_disposition_t
sctp_sf_do_asconf
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
// FIXME: Handle the ASCONF chunk
return
SCTP_DISPOSITION_CONSUME
;
}
/*
* ADDIP Section 4.3 General rules for address manipulation
* When building TLV parameters for the ASCONF Chunk that will add or
* delete IP addresses the D0 to D13 rules should be applied:
*/
sctp_disposition_t
sctp_sf_do_asconf_ack
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
// FIXME: Handle the ASCONF-ACK chunk
return
SCTP_DISPOSITION_CONSUME
;
}
/*
/*
* Process an unknown chunk.
* Process an unknown chunk.
*
*
...
@@ -3815,6 +3845,26 @@ sctp_disposition_t sctp_sf_do_prm_requestheartbeat(
...
@@ -3815,6 +3845,26 @@ sctp_disposition_t sctp_sf_do_prm_requestheartbeat(
commands
);
commands
);
}
}
/*
* ADDIP Section 4.1 ASCONF Chunk Procedures
* When an endpoint has an ASCONF signaled change to be sent to the
* remote endpoint it should do A1 to A9
*/
sctp_disposition_t
sctp_sf_do_prm_asconf
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
struct
sctp_chunk
*
chunk
=
arg
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SETUP_T4
,
SCTP_CHUNK
(
chunk
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_START
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T4_RTO
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
chunk
));
return
SCTP_DISPOSITION_CONSUME
;
}
/*
/*
* Ignore the primitive event
* Ignore the primitive event
*
*
...
@@ -4213,6 +4263,21 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
...
@@ -4213,6 +4263,21 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
return
SCTP_DISPOSITION_NOMEM
;
return
SCTP_DISPOSITION_NOMEM
;
}
}
/*
* ADDIP Section 4.1 ASCONF CHunk Procedures
* If the T-4 RTO timer expires the endpoint should do B1 to B5
*/
sctp_disposition_t
sctp_sf_t4_timer_expire
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
// FIXME: need to handle t4 expire
return
SCTP_DISPOSITION_CONSUME
;
}
/* sctpimpguide-05 Section 2.12.2
/* sctpimpguide-05 Section 2.12.2
* The sender of the SHUTDOWN MAY also start an overall guard timer
* The sender of the SHUTDOWN MAY also start an overall guard timer
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
...
...
net/sctp/sm_statetable.c
View file @
f6578e8d
...
@@ -436,6 +436,55 @@ const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_ST
...
@@ -436,6 +436,55 @@ const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_ST
TYPE_SCTP_SHUTDOWN_COMPLETE
,
TYPE_SCTP_SHUTDOWN_COMPLETE
,
};
/* state_fn_t chunk_event_table[][] */
};
/* state_fn_t chunk_event_table[][] */
#define TYPE_SCTP_ASCONF { \
/* SCTP_STATE_EMPTY */
\
{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{.fn = sctp_sf_do_asconf, .name = "sctp_sf_do_asconf"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_ASCONF */
#define TYPE_SCTP_ASCONF_ACK { \
/* SCTP_STATE_EMPTY */
\
{.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{.fn = sctp_sf_do_asconf_ack, .name = "sctp_sf_do_asconf_ack"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_ASCONF_ACK */
/* The primary index for this table is the chunk type.
* The secondary index for this table is the state.
*/
const
sctp_sm_table_entry_t
addip_chunk_event_table
[
SCTP_NUM_ADDIP_CHUNK_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
TYPE_SCTP_ASCONF
,
TYPE_SCTP_ASCONF_ACK
,
};
/*state_fn_t addip_chunk_event_table[][] */
static
const
sctp_sm_table_entry_t
static
const
sctp_sm_table_entry_t
chunk_event_table_unknown
[
SCTP_STATE_NUM_STATES
]
=
{
chunk_event_table_unknown
[
SCTP_STATE_NUM_STATES
]
=
{
...
@@ -582,6 +631,26 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
...
@@ -582,6 +631,26 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
.name = "sctp_sf_do_prm_requestheartbeat"}, \
.name = "sctp_sf_do_prm_requestheartbeat"}, \
}
/* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
}
/* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
#define TYPE_SCTP_PRIMITIVE_ASCONF { \
/* SCTP_STATE_EMPTY */
\
{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
/* SCTP_STATE_ESTABLISHED */
\
{.fn = sctp_sf_do_prm_asconf, .name = "sctp_sf_do_prm_asconf"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
}
/* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
/* The primary index for this table is the primitive type.
/* The primary index for this table is the primitive type.
* The secondary index for this table is the state.
* The secondary index for this table is the state.
...
@@ -592,6 +661,7 @@ const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP
...
@@ -592,6 +661,7 @@ const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP
TYPE_SCTP_PRIMITIVE_ABORT
,
TYPE_SCTP_PRIMITIVE_ABORT
,
TYPE_SCTP_PRIMITIVE_SEND
,
TYPE_SCTP_PRIMITIVE_SEND
,
TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT
,
TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT
,
TYPE_SCTP_PRIMITIVE_ASCONF
,
};
};
#define TYPE_SCTP_OTHER_NO_PENDING_TSN { \
#define TYPE_SCTP_OTHER_NO_PENDING_TSN { \
...
@@ -726,6 +796,27 @@ const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_N
...
@@ -726,6 +796,27 @@ const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_N
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
}
}
#define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \
/* SCTP_STATE_EMPTY */
\
{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{.fn = sctp_sf_t4_timer_expire, .name = "sctp_sf_t4_timer_expire"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \
#define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \
/* SCTP_STATE_EMPTY */
\
/* SCTP_STATE_EMPTY */
\
{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
...
@@ -817,6 +908,7 @@ const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STA
...
@@ -817,6 +908,7 @@ const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STA
TYPE_SCTP_EVENT_TIMEOUT_T1_INIT
,
TYPE_SCTP_EVENT_TIMEOUT_T1_INIT
,
TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
,
TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
,
TYPE_SCTP_EVENT_TIMEOUT_T3_RTX
,
TYPE_SCTP_EVENT_TIMEOUT_T3_RTX
,
TYPE_SCTP_EVENT_TIMEOUT_T4_RTO
,
TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
,
TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
,
TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT
,
TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT
,
TYPE_SCTP_EVENT_TIMEOUT_SACK
,
TYPE_SCTP_EVENT_TIMEOUT_SACK
,
...
@@ -833,5 +925,10 @@ const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
...
@@ -833,5 +925,10 @@ const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
return
&
chunk_event_table
[
cid
][
state
];
return
&
chunk_event_table
[
cid
][
state
];
}
}
if
(
cid
>=
SCTP_CID_ADDIP_MIN
&&
cid
<=
SCTP_CID_ADDIP_MAX
)
{
return
&
addip_chunk_event_table
[
cid
-
SCTP_CID_ADDIP_MIN
][
state
];
}
return
&
chunk_event_table_unknown
[
state
];
return
&
chunk_event_table_unknown
[
state
];
}
}
net/sctp/socket.c
View file @
f6578e8d
...
@@ -455,47 +455,6 @@ int sctp_bindx_add(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
...
@@ -455,47 +455,6 @@ int sctp_bindx_add(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
}
}
}
}
/* Notify the peer(s), assuming we have (an) association(s).
* FIXME: for UDP, we have a 1-1-many mapping amongst sk, ep and asoc,
* so we don't have to do much work on locating associations.
*
* However, when the separation of ep and asoc kicks in, especially
* for TCP style connection, it becomes n-1-n mapping. We will need
* to do more fine work. Until then, hold my peace.
* --xguo
*
* Really, I don't think that will be a problem. The bind()
* call on a socket will either know the endpoint
* (e.g. TCP-style listen()ing socket, or UDP-style socket),
* or exactly one association. The former case is EXACTLY
* what we have now. In the former case we know the
* association already. --piggy
*
* This code will be working on either a UDP style or a TCP style
* socket, or say either an endpoint or an association. The socket
* type verification code need to be added later before calling the
* ADDIP code.
* --daisy
*/
#ifdef CONFIG_IP_SCTP_ADDIP
/* Add these addresses to all associations on this endpoint. */
if
(
retval
>=
0
)
{
struct
list_head
*
pos
;
struct
sctp_endpoint
*
ep
;
struct
sctp_association
*
asoc
;
ep
=
sctp_sk
(
sk
)
->
ep
;
list_for_each
(
pos
,
&
ep
->
asocs
)
{
asoc
=
list_entry
(
pos
,
struct
sctp_association
,
asocs
);
sctp_addip_addr_config
(
asoc
,
SCTP_PARAM_ADD_IP
,
addrs
,
addrcnt
);
}
}
#endif
return
retval
;
return
retval
;
}
}
...
@@ -591,28 +550,6 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
...
@@ -591,28 +550,6 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
}
}
}
}
/*
* This code will be working on either a UDP style or a TCP style
* socket, * or say either an endpoint or an association. The socket
* type verification code need to be added later before calling the
* ADDIP code.
* --daisy
*/
#ifdef CONFIG_IP_SCTP_ADDIP
/* Remove these addresses from all associations on this endpoint. */
if
(
retval
>=
0
)
{
struct
list_head
*
pos
;
struct
sctp_endpoint
*
ep
;
struct
sctp_association
*
asoc
;
ep
=
sctp_sk
(
sk
)
->
ep
;
list_for_each
(
pos
,
&
ep
->
asocs
)
{
asoc
=
list_entry
(
pos
,
struct
sctp_association
,
asocs
);
sctp_addip_addr_config
(
asoc
,
SCTP_PARAM_DEL_IP
,
addrs
,
addrcnt
);
}
}
#endif
return
retval
;
return
retval
;
}
}
...
...
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