Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
dd18325f
Commit
dd18325f
authored
Sep 25, 2002
by
Jon Grimm
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux.bkbits.net/linux-2.5
into jgrimm.austin.ibm.com:/home/jgrimm/bk/test.merge.38
parents
5dd6a6e5
372f525b
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1671 additions
and
1154 deletions
+1671
-1154
include/net/sctp/constants.h
include/net/sctp/constants.h
+1
-0
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+2
-1
include/net/sctp/sm.h
include/net/sctp/sm.h
+8
-0
include/net/sctp/structs.h
include/net/sctp/structs.h
+14
-1
net/sctp/adler32.c
net/sctp/adler32.c
+1
-1
net/sctp/associola.c
net/sctp/associola.c
+32
-20
net/sctp/bind_addr.c
net/sctp/bind_addr.c
+17
-17
net/sctp/command.c
net/sctp/command.c
+13
-13
net/sctp/debug.c
net/sctp/debug.c
+1
-0
net/sctp/endpointola.c
net/sctp/endpointola.c
+47
-42
net/sctp/input.c
net/sctp/input.c
+16
-16
net/sctp/ipv6.c
net/sctp/ipv6.c
+98
-17
net/sctp/output.c
net/sctp/output.c
+37
-40
net/sctp/outqueue.c
net/sctp/outqueue.c
+88
-63
net/sctp/primitive.c
net/sctp/primitive.c
+14
-14
net/sctp/protocol.c
net/sctp/protocol.c
+94
-14
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+30
-21
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+43
-21
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+501
-247
net/sctp/sm_statetable.c
net/sctp/sm_statetable.c
+492
-451
net/sctp/socket.c
net/sctp/socket.c
+54
-93
net/sctp/transport.c
net/sctp/transport.c
+20
-20
net/sctp/ulpevent.c
net/sctp/ulpevent.c
+48
-42
No files found.
include/net/sctp/constants.h
View file @
dd18325f
...
...
@@ -112,6 +112,7 @@ typedef enum {
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
,
SCTP_EVENT_TIMEOUT_T3_RTX
,
SCTP_EVENT_TIMEOUT_T4_RTO
,
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
,
SCTP_EVENT_TIMEOUT_HEARTBEAT
,
SCTP_EVENT_TIMEOUT_SACK
,
SCTP_EVENT_TIMEOUT_AUTOCLOSE
,
...
...
include/net/sctp/sctp.h
View file @
dd18325f
...
...
@@ -114,7 +114,8 @@ extern sctp_protocol_t sctp_proto;
extern
struct
sock
*
sctp_get_ctl_sock
(
void
);
extern
int
sctp_copy_local_addr_list
(
sctp_protocol_t
*
,
sctp_bind_addr_t
*
,
sctp_scope_t
,
int
priority
,
int
flags
);
extern
sctp_pf_t
*
sctp_get_pf_specific
(
int
family
);
extern
void
sctp_set_pf_specific
(
int
family
,
sctp_pf_t
*
);
/*
* sctp_socket.c
...
...
include/net/sctp/sm.h
View file @
dd18325f
...
...
@@ -107,6 +107,9 @@ sctp_state_fn_t sctp_sf_timer_ignore;
sctp_state_fn_t
sctp_sf_do_9_1_abort
;
sctp_state_fn_t
sctp_sf_cookie_wait_abort
;
sctp_state_fn_t
sctp_sf_cookie_echoed_abort
;
sctp_state_fn_t
sctp_sf_shutdown_pending_abort
;
sctp_state_fn_t
sctp_sf_shutdown_sent_abort
;
sctp_state_fn_t
sctp_sf_shutdown_ack_sent_abort
;
sctp_state_fn_t
sctp_sf_do_5_1B_init
;
sctp_state_fn_t
sctp_sf_do_5_1C_ack
;
sctp_state_fn_t
sctp_sf_do_5_1D_ce
;
...
...
@@ -119,6 +122,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_t1_timer_expire
;
sctp_state_fn_t
sctp_sf_t2_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_beat_8_3
;
sctp_state_fn_t
sctp_sf_backbeat_8_3
;
...
...
@@ -134,6 +138,7 @@ sctp_state_fn_t sctp_sf_discard_chunk;
sctp_state_fn_t
sctp_sf_do_5_2_1_siminit
;
sctp_state_fn_t
sctp_sf_do_5_2_2_dupinit
;
sctp_state_fn_t
sctp_sf_do_5_2_4_dupcook
;
sctp_state_fn_t
sctp_sf_unk_chunk
;
/* Prototypes for primitive event state functions. */
sctp_state_fn_t
sctp_sf_do_prm_asoc
;
...
...
@@ -144,6 +149,9 @@ sctp_state_fn_t sctp_sf_cookie_echoed_prm_shutdown;
sctp_state_fn_t
sctp_sf_do_9_1_prm_abort
;
sctp_state_fn_t
sctp_sf_cookie_wait_prm_abort
;
sctp_state_fn_t
sctp_sf_cookie_echoed_prm_abort
;
sctp_state_fn_t
sctp_sf_shutdown_pending_prm_abort
;
sctp_state_fn_t
sctp_sf_shutdown_sent_prm_abort
;
sctp_state_fn_t
sctp_sf_shutdown_ack_sent_prm_abort
;
sctp_state_fn_t
sctp_sf_error_closed
;
sctp_state_fn_t
sctp_sf_error_shutdown
;
sctp_state_fn_t
sctp_sf_ignore_primitive
;
...
...
include/net/sctp/structs.h
View file @
dd18325f
...
...
@@ -255,6 +255,12 @@ typedef struct sctp_func {
sctp_func_t
*
sctp_get_af_specific
(
const
sockaddr_storage_t
*
address
);
/* Protocol family functions. */
typedef
struct
sctp_pf
{
void
(
*
event_msgname
)(
sctp_ulpevent_t
*
,
char
*
,
int
*
);
void
(
*
skb_msgname
)(
struct
sk_buff
*
,
char
*
,
int
*
);
}
sctp_pf_t
;
/* SCTP Socket type: UDP or TCP style. */
typedef
enum
{
SCTP_SOCKET_UDP
=
0
,
...
...
@@ -280,6 +286,7 @@ struct sctp_opt {
__u32
autoclose
;
__u8
nodelay
;
__u8
disable_fragments
;
sctp_pf_t
*
pf
;
};
...
...
@@ -845,6 +852,7 @@ int sctp_outqueue_set_output_handlers(sctp_outqueue_t *,
sctp_outqueue_ohandler_force_t
force
);
void
sctp_outqueue_restart
(
sctp_outqueue_t
*
);
void
sctp_retransmit
(
sctp_outqueue_t
*
,
sctp_transport_t
*
,
__u8
);
void
sctp_retransmit_mark
(
sctp_outqueue_t
*
,
sctp_transport_t
*
,
__u8
);
/* These bind address data fields common between endpoints and associations */
...
...
@@ -1128,6 +1136,11 @@ struct SCTP_association {
*/
sctp_transport_t
*
primary_path
;
/* Cache the primary path address here, when we
* need a an address for msg_name.
*/
sockaddr_storage_t
primary_addr
;
/* active_path
* The path that we are currently using to
* transmit new data and most control chunks.
...
...
@@ -1183,7 +1196,7 @@ struct SCTP_association {
int
next_dup_tsn
;
/* Do we need to sack the peer? */
in
t
sack_needed
;
uint8_
t
sack_needed
;
/* These are capabilities which our peer advertised. */
__u8
ecn_capable
;
/* Can peer do ECN? */
...
...
net/sctp/adler32.c
View file @
dd18325f
...
...
@@ -96,7 +96,7 @@ unsigned long update_adler32(unsigned long adler,
* one subtract at the MOST, since buf[n]
* is a max of 255.
*/
if
(
s1
>=
BASE
)
if
(
s1
>=
BASE
)
s1
-=
BASE
;
/* s2 = (s2 + s1) % BASE */
...
...
net/sctp/associola.c
View file @
dd18325f
...
...
@@ -288,7 +288,6 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
return
NULL
;
}
/* Free this association if possible. There may still be users, so
* the actual deallocation may be delayed.
*/
...
...
@@ -330,6 +329,11 @@ void sctp_association_free(sctp_association_t *asoc)
sctp_association_put
(
asoc
);
}
/* Free peer's cached cookie. */
if
(
asoc
->
peer
.
cookie
)
{
kfree
(
asoc
->
peer
.
cookie
);
}
/* Release the transport structures. */
list_for_each_safe
(
pos
,
temp
,
&
asoc
->
peer
.
transport_addr_list
)
{
transport
=
list_entry
(
pos
,
sctp_transport_t
,
transports
);
...
...
@@ -342,7 +346,6 @@ void sctp_association_free(sctp_association_t *asoc)
sctp_association_put
(
asoc
);
}
/* Cleanup and free up an association. */
static
void
sctp_association_destroy
(
sctp_association_t
*
asoc
)
{
...
...
@@ -387,8 +390,7 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
asoc
->
peer
.
port
=
*
port
;
}
SCTP_ASSERT
(
*
port
==
asoc
->
peer
.
port
,
":Invalid port
\n
"
,
return
NULL
);
SCTP_ASSERT
(
*
port
==
asoc
->
peer
.
port
,
":Invalid port
\n
"
,
return
NULL
);
/* Check to see if this is a duplicate. */
peer
=
sctp_assoc_lookup_paddr
(
asoc
,
addr
);
...
...
@@ -464,6 +466,16 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
/* Attach the remote transport to our asoc. */
list_add_tail
(
&
peer
->
transports
,
&
asoc
->
peer
.
transport_addr_list
);
/* If we do not yet have a primary path, set one. */
if
(
NULL
==
asoc
->
peer
.
primary_path
)
{
asoc
->
peer
.
primary_path
=
peer
;
/* Set a default msg_name for events. */
memcpy
(
&
asoc
->
peer
.
primary_addr
,
&
peer
->
ipaddr
,
sizeof
(
sockaddr_storage_t
));
asoc
->
peer
.
active_path
=
peer
;
asoc
->
peer
.
retran_path
=
peer
;
}
/* If we do not yet have a primary path, set one. */
if
(
NULL
==
asoc
->
peer
.
primary_path
)
{
asoc
->
peer
.
primary_path
=
peer
;
...
...
net/sctp/bind_addr.c
View file @
dd18325f
net/sctp/command.c
View file @
dd18325f
net/sctp/debug.c
View file @
dd18325f
...
...
@@ -198,6 +198,7 @@ static const char *sctp_timer_tbl[] = {
"TIMEOUT_T2_SHUTDOWN"
,
"TIMEOUT_T3_RTX"
,
"TIMEOUT_T4_RTO"
,
"TIMEOUT_T5_SHUTDOWN_GUARD"
,
"TIMEOUT_HEARTBEAT"
,
"TIMEOUT_SACK"
,
"TIMEOUT_AUTOCLOSE"
,
...
...
net/sctp/endpointola.c
View file @
dd18325f
...
...
@@ -92,6 +92,7 @@ sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *proto,
sctp_endpoint_t
*
sctp_endpoint_init
(
sctp_endpoint_t
*
ep
,
sctp_protocol_t
*
proto
,
struct
sock
*
sk
,
int
priority
)
{
sctp_opt_t
*
sp
=
sctp_sk
(
sk
);
memset
(
ep
,
0
,
sizeof
(
sctp_endpoint_t
));
/* Initialize the base structure. */
...
...
@@ -129,22 +130,30 @@ sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, sctp_protocol_t *proto,
/* Set up the base timeout information. */
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_NONE
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
=
SCTP_DEFAULT_TIMEOUT_T1_COOKIE
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
=
SCTP_DEFAULT_TIMEOUT_T1_INIT
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
]
=
sctp_sk
(
sk
)
->
rtoinfo
.
srto_initial
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_COOKIE
]
=
SCTP_DEFAULT_TIMEOUT_T1_COOKIE
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T1_INIT
]
=
SCTP_DEFAULT_TIMEOUT_T1_INIT
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
]
=
sp
->
rtoinfo
.
srto_initial
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T3_RTX
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T4_RTO
]
=
0
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_HEARTBEAT
]
=
SCTP_DEFAULT_TIMEOUT_HEARTBEAT
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_SACK
]
=
SCTP_DEFAULT_TIMEOUT_SACK
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
]
=
sctp_sk
(
sk
)
->
autoclose
*
HZ
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_PMTU_RAISE
]
=
SCTP_DEFAULT_TIMEOUT_PMTU_RAISE
;
/* sctpimpguide-05 Section 2.12.2
* If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the
* recommended value of 5 times 'RTO.Max'.
*/
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
]
=
5
*
sp
->
rtoinfo
.
srto_max
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_HEARTBEAT
]
=
SCTP_DEFAULT_TIMEOUT_HEARTBEAT
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_SACK
]
=
SCTP_DEFAULT_TIMEOUT_SACK
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
]
=
sp
->
autoclose
*
HZ
;
ep
->
timeouts
[
SCTP_EVENT_TIMEOUT_PMTU_RAISE
]
=
SCTP_DEFAULT_TIMEOUT_PMTU_RAISE
;
/* Set up the default send/receive buffer space. */
...
...
@@ -251,7 +260,8 @@ sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *ep,
* We do a linear search of the associations for this endpoint.
* We return the matching transport address too.
*/
sctp_association_t
*
__sctp_endpoint_lookup_assoc
(
const
sctp_endpoint_t
*
endpoint
,
sctp_association_t
*
__sctp_endpoint_lookup_assoc
(
const
sctp_endpoint_t
*
endpoint
,
const
sockaddr_storage_t
*
paddr
,
sctp_transport_t
**
transport
)
{
...
...
@@ -360,10 +370,5 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep)
/* Is this the right way to pass errors up to the ULP? */
if
(
error
)
ep
->
base
.
sk
->
err
=
-
error
;
out:
}
net/sctp/input.c
View file @
dd18325f
net/sctp/ipv6.c
View file @
dd18325f
...
...
@@ -189,6 +189,80 @@ int sctp_v6_get_dst_mtu(const sockaddr_storage_t *address)
return
dst_mtu
;
}
/* Initialize a PF_INET6 socket msg_name. */
static
void
sctp_inet6_msgname
(
char
*
msgname
,
int
*
addr_len
)
{
struct
sockaddr_in6
*
sin6
;
sin6
=
(
struct
sockaddr_in6
*
)
msgname
;
sin6
->
sin6_family
=
AF_INET6
;
sin6
->
sin6_flowinfo
=
0
;
sin6
->
sin6_scope_id
=
0
;
*
addr_len
=
sizeof
(
struct
sockaddr_in6
);
}
/* Initialize a PF_INET msgname from a ulpevent. */
static
void
sctp_inet6_event_msgname
(
sctp_ulpevent_t
*
event
,
char
*
msgname
,
int
*
addrlen
)
{
struct
sockaddr_in6
*
sin6
,
*
sin6from
;
if
(
msgname
)
{
sockaddr_storage_t
*
addr
;
sctp_inet6_msgname
(
msgname
,
addrlen
);
sin6
=
(
struct
sockaddr_in6
*
)
msgname
;
sin6
->
sin6_port
=
htons
(
event
->
asoc
->
peer
.
port
);
addr
=
&
event
->
asoc
->
peer
.
primary_addr
;
/* Note: If we go to a common v6 format, this code
* will change.
*/
/* Map ipv4 address into v4-mapped-on-v6 address. */
if
(
AF_INET
==
addr
->
sa
.
sa_family
)
{
/* FIXME: Easy, but there was no way to test this
* yet.
*/
return
;
}
sin6from
=
&
event
->
asoc
->
peer
.
primary_addr
.
v6
;
ipv6_addr_copy
(
&
sin6
->
sin6_addr
,
&
sin6from
->
sin6_addr
);
}
}
/* Initialize a msg_name from an inbound skb. */
static
void
sctp_inet6_skb_msgname
(
struct
sk_buff
*
skb
,
char
*
msgname
,
int
*
addr_len
)
{
struct
sctphdr
*
sh
;
struct
sockaddr_in6
*
sin6
;
if
(
msgname
)
{
sctp_inet6_msgname
(
msgname
,
addr_len
);
sin6
=
(
struct
sockaddr_in6
*
)
msgname
;
sh
=
(
struct
sctphdr
*
)
skb
->
h
.
raw
;
sin6
->
sin6_port
=
sh
->
source
;
/* FIXME: Map ipv4 address into v4-mapped-on-v6 address. */
if
(
__constant_htons
(
ETH_P_IP
)
==
skb
->
protocol
)
{
/* FIXME: Easy, but there was no way to test this
* yet.
*/
return
;
}
/* Otherwise, just copy the v6 address. */
ipv6_addr_copy
(
&
sin6
->
sin6_addr
,
&
skb
->
nh
.
ipv6h
->
saddr
);
if
(
ipv6_addr_type
(
&
sin6
->
sin6_addr
)
&
IPV6_ADDR_LINKLOCAL
)
{
struct
inet6_skb_parm
*
opt
=
(
struct
inet6_skb_parm
*
)
skb
->
cb
;
sin6
->
sin6_scope_id
=
opt
->
iif
;
}
}
}
static
struct
proto_ops
inet6_seqpacket_ops
=
{
.
family
=
PF_INET6
,
.
release
=
inet6_release
,
...
...
@@ -238,15 +312,22 @@ static sctp_func_t sctp_ipv6_specific = {
.
sa_family
=
AF_INET6
,
};
static
sctp_pf_t
sctp_pf_inet6_specific
=
{
.
event_msgname
=
sctp_inet6_event_msgname
,
.
skb_msgname
=
sctp_inet6_skb_msgname
,
};
/* Initialize IPv6 support and register with inet6 stack. */
int
sctp_v6_init
(
void
)
{
/* Add SCTPv6 to inetsw6 linked list. */
inet6_register_protosw
(
&
sctpv6_protosw
);
/* Register inet6 protocol. */
inet6_add_protocol
(
&
sctpv6_protocol
);
/* Register the SCTP specfic PF_INET6 functions. */
sctp_set_pf_specific
(
PF_INET6
,
&
sctp_pf_inet6_specific
);
/* Fill in address family info. */
INIT_LIST_HEAD
(
&
sctp_ipv6_specific
.
list
);
list_add_tail
(
&
sctp_ipv6_specific
.
list
,
&
sctp_proto
.
address_families
);
...
...
net/sctp/output.c
View file @
dd18325f
...
...
@@ -129,7 +129,8 @@ void sctp_packet_free(sctp_packet_t *packet)
* as it can fit in the packet, but any more data that does not fit in this
* packet can be sent only after receiving the COOKIE_ACK.
*/
sctp_xmit_t
sctp_packet_transmit_chunk
(
sctp_packet_t
*
packet
,
sctp_chunk_t
*
chunk
)
sctp_xmit_t
sctp_packet_transmit_chunk
(
sctp_packet_t
*
packet
,
sctp_chunk_t
*
chunk
)
{
sctp_xmit_t
retval
;
int
error
=
0
;
...
...
@@ -181,8 +182,8 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
/* Both control chunks and data chunks with TSNs are
* non-fragmentable.
*/
int
fragmentable
=
sctp_chunk_is_data
(
chunk
)
&&
(
!
chunk
->
has_tsn
);
int
fragmentable
=
sctp_chunk_is_data
(
chunk
)
&&
(
!
chunk
->
has_tsn
);
if
(
packet_empty
)
{
if
(
fragmentable
)
{
retval
=
SCTP_XMIT_MUST_FRAG
;
...
...
@@ -221,10 +222,8 @@ sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
}
/* It is OK to send this chunk. */
skb_queue_tail
(
&
packet
->
chunks
,
(
struct
sk_buff
*
)
chunk
);
skb_queue_tail
(
&
packet
->
chunks
,
(
struct
sk_buff
*
)
chunk
);
packet
->
size
+=
chunk_len
;
finish:
return
retval
;
}
...
...
@@ -337,7 +336,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
}
/* Build the SCTP header. */
sh
=
(
struct
sctphdr
*
)
skb_push
(
nskb
,
sizeof
(
struct
sctphdr
));
sh
=
(
struct
sctphdr
*
)
skb_push
(
nskb
,
sizeof
(
struct
sctphdr
));
sh
->
source
=
htons
(
packet
->
source_port
);
sh
->
dest
=
htons
(
packet
->
destination_port
);
...
...
@@ -467,7 +466,8 @@ static void sctp_packet_reset(sctp_packet_t *packet)
}
/* This private function handles the specifics of appending DATA chunks. */
static
sctp_xmit_t
sctp_packet_append_data
(
sctp_packet_t
*
packet
,
sctp_chunk_t
*
chunk
)
static
sctp_xmit_t
sctp_packet_append_data
(
sctp_packet_t
*
packet
,
sctp_chunk_t
*
chunk
)
{
sctp_xmit_t
retval
=
SCTP_XMIT_OK
;
size_t
datasize
,
rwnd
,
inflight
;
...
...
@@ -502,12 +502,13 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *
}
}
/* sctpimpguide-05 2.14.2 D) When the time comes for the sender to
/* 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
* if
((flightsize + Max.Burst *
MTU) < cwnd)
* cwnd = flightsize + Max.Burst
*
MTU
*/
max_burst_bytes
=
transport
->
asoc
->
max_burst
*
transport
->
asoc
->
pmtu
;
if
((
transport
->
flight_size
+
max_burst_bytes
)
<
transport
->
cwnd
)
{
...
...
@@ -552,7 +553,3 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *
finish:
return
retval
;
}
net/sctp/outqueue.c
View file @
dd18325f
...
...
@@ -196,23 +196,14 @@ int sctp_push_outqueue(sctp_outqueue_t *q, sctp_chunk_t *chunk)
return
error
;
}
/* Mark all the eligible packets on a transport for retransmission and force
* one packet out.
*/
void
sctp_retransmit
(
sctp_outqueue_t
*
q
,
sctp_transport_t
*
transport
,
/* Mark all the eligible packets on a transport for retransmission. */
void
sctp_retransmit_mark
(
sctp_outqueue_t
*
q
,
sctp_transport_t
*
transport
,
__u8
fast_retransmit
)
{
struct
list_head
*
lchunk
;
sctp_chunk_t
*
chunk
;
int
error
=
0
;
struct
list_head
tlist
;
if
(
fast_retransmit
)
{
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_FAST_RTX
);
}
else
{
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_T3_RTX
);
}
INIT_LIST_HEAD
(
&
tlist
);
while
(
!
list_empty
(
&
transport
->
transmitted
))
{
...
...
@@ -276,7 +267,26 @@ void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport,
transport
->
flight_size
,
transport
->
partial_bytes_acked
);
}
/* Mark all the eligible packets on a transport for retransmission and force
* one packet out.
*/
void
sctp_retransmit
(
sctp_outqueue_t
*
q
,
sctp_transport_t
*
transport
,
__u8
fast_retransmit
)
{
int
error
=
0
;
if
(
fast_retransmit
)
{
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_FAST_RTX
);
}
else
{
sctp_transport_lower_cwnd
(
transport
,
SCTP_LOWER_CWND_T3_RTX
);
}
sctp_retransmit_mark
(
q
,
transport
,
fast_retransmit
);
error
=
sctp_flush_outqueue
(
q
,
/* rtx_timeout */
1
);
if
(
error
)
q
->
asoc
->
base
.
sk
->
err
=
-
error
;
}
...
...
@@ -370,8 +380,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
/* The append was successful, so add this chunk to
* the transmitted list.
*/
list_add_tail
(
lchunk
,
&
transport
->
transmitted
);
list_add_tail
(
lchunk
,
&
transport
->
transmitted
);
*
start_timer
=
1
;
q
->
empty
=
0
;
...
...
@@ -389,8 +398,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
* chunk that is currently in the process of fragmentation.
*/
void
sctp_xmit_frag
(
sctp_outqueue_t
*
q
,
struct
sk_buff
*
pos
,
sctp_packet_t
*
packet
,
sctp_chunk_t
*
frag
,
__u32
tsn
)
sctp_packet_t
*
packet
,
sctp_chunk_t
*
frag
,
__u32
tsn
)
{
sctp_transport_t
*
transport
=
packet
->
transport
;
struct
sk_buff_head
*
queue
=
&
q
->
out
;
...
...
@@ -499,7 +507,8 @@ void sctp_xmit_fragmented_chunks(sctp_outqueue_t *q, sctp_packet_t *packet,
* fragments. It returns the first fragment with the frag_list field holding
* the remaining fragments.
*/
sctp_chunk_t
*
sctp_fragment_chunk
(
sctp_chunk_t
*
chunk
,
size_t
max_frag_data_len
)
sctp_chunk_t
*
sctp_fragment_chunk
(
sctp_chunk_t
*
chunk
,
size_t
max_frag_data_len
)
{
sctp_association_t
*
asoc
=
chunk
->
asoc
;
void
*
data_ptr
=
chunk
->
subh
.
data_hdr
;
...
...
@@ -533,11 +542,14 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk, size_t max_frag_data_len)
/* Make the middle fragments. */
while
(
chunk_data_len
>
max_frag_data_len
)
{
frag
=
sctp_make_datafrag
(
asoc
,
sinfo
,
max_frag_data_len
,
data_ptr
,
SCTP_DATA_MIDDLE_FRAG
,
ssn
);
data_ptr
,
SCTP_DATA_MIDDLE_FRAG
,
ssn
);
if
(
!
frag
)
goto
err
;
/* Add the middle fragment to the first fragment's frag_list. */
/* Add the middle fragment to the first fragment's
* frag_list.
*/
list_add_tail
(
&
frag
->
frag_list
,
frag_list
);
chunk_data_len
-=
max_frag_data_len
;
...
...
@@ -674,7 +686,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
(
void
)
(
*
q
->
build_output
)(
&
singleton
,
chunk
);
error
=
(
*
q
->
force_output
)(
&
singleton
);
if
(
error
<
0
)
return
(
error
)
;
return
error
;
break
;
case
SCTP_CID_ABORT
:
...
...
@@ -705,10 +717,10 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
/* Is it OK to send data chunks? */
switch
(
asoc
->
state
)
{
case
SCTP_STATE_COOKIE_ECHOED
:
/* Only allow bundling
, if
this packet has a COOKIE-ECHO
/* Only allow bundling
when
this packet has a COOKIE-ECHO
* chunk.
*/
if
(
packet
&&
!
packet
->
has_cookie_echo
)
if
(
!
packet
||
!
packet
->
has_cookie_echo
)
break
;
/* fallthru */
...
...
@@ -748,6 +760,12 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
if
(
start_timer
)
sctp_transport_reset_timers
(
transport
);
/* This can happen on COOKIE-ECHO resend. Only
* one chunk can get bundled with a COOKIE-ECHO.
*/
if
(
packet
->
has_cookie_echo
)
goto
sctp_flush_out
;
}
/* Finally, transmit new packets. */
...
...
@@ -813,8 +831,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
chunk
->
skb
?
chunk
->
skb
->
head
:
0
,
chunk
->
skb
?
atomic_read
(
&
chunk
->
skb
->
users
)
:
-
1
);
atomic_read
(
&
chunk
->
skb
->
users
)
:
-
1
);
/* Add the chunk to the packet. */
status
=
(
*
q
->
build_output
)(
packet
,
chunk
);
...
...
@@ -827,7 +844,8 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
*/
SCTP_DEBUG_PRINTK
(
"sctp_flush_outqueue: could"
"not transmit TSN: 0x%x, status: %d
\n
"
,
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
status
);
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
status
);
skb_queue_head
(
queue
,
(
struct
sk_buff
*
)
chunk
);
goto
sctp_flush_out
;
break
;
...
...
@@ -857,7 +875,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
default:
BUG
();
}
;
}
/* BUG: We assume that the (*q->force_output())
* call below will succeed all the time and add the
...
...
@@ -875,13 +893,19 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
sctp_transport_reset_timers
(
transport
);
q
->
empty
=
0
;
/* Only let one DATA chunk get bundled with a
* COOKIE-ECHO chunk.
*/
if
(
packet
->
has_cookie_echo
)
goto
sctp_flush_out
;
}
break
;
default:
/* Do nothing. */
break
;
}
;
}
sctp_flush_out:
/* Before returning, examine all the transports touched in
...
...
@@ -986,8 +1010,7 @@ int sctp_sack_outqueue(sctp_outqueue_t *q, sctp_sackhdr_t *sack)
ctsn
=
q
->
asoc
->
ctsn_ack_point
;
SCTP_DEBUG_PRINTK
(
"%s: sack Cumulative TSN Ack is 0x%x.
\n
"
,
__FUNCTION__
,
sack_ctsn
);
__FUNCTION__
,
sack_ctsn
);
SCTP_DEBUG_PRINTK
(
"%s: Cumulative TSN Ack of association "
"%p is 0x%x.
\n
"
,
__FUNCTION__
,
q
->
asoc
,
ctsn
);
...
...
@@ -1114,8 +1137,9 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
* 6.3.1 C5) Karn's algorithm: RTT measurements
* MUST NOT be made using packets that were
* retransmitted (and thus for which it is
* ambiguous whether the reply was for the first
* instance of the packet or a later instance).
* ambiguous whether the reply was for the
* first instance of the packet or a later
* instance).
*/
if
((
!
tchunk
->
tsn_gap_acked
)
&&
(
1
==
tchunk
->
num_times_sent
)
&&
...
...
@@ -1150,15 +1174,15 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
* 'Stray DATA chunk(s)' record the highest TSN
* reported as newly acknowledged, call this
* value 'HighestTSNinSack'. A newly
* acknowledged DATA chunk is one not
previously
* acknowledged in a SACK.
* acknowledged DATA chunk is one not
*
previously
acknowledged in a SACK.
*
* When the SCTP sender of data receives a SACK
* chunk that acknowledges, for the first time,
* the receipt of a DATA chunk, all the still
* unacknowledged DATA chunks whose TSN is
older
*
than that newly acknowledged DATA chunk, are
* qualified as 'Stray DATA chunks'.
* unacknowledged DATA chunks whose TSN is
*
older than that newly acknowledged DATA
*
chunk, are
qualified as 'Stray DATA chunks'.
*/
if
(
!
tchunk
->
tsn_gap_acked
)
{
tchunk
->
tsn_gap_acked
=
1
;
...
...
@@ -1217,8 +1241,8 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
}
else
{
if
(
tchunk
->
tsn_gap_acked
)
{
SCTP_DEBUG_PRINTK
(
"%s: Receiver reneged on
data
"
"TSN: 0x%x
\n
"
,
SCTP_DEBUG_PRINTK
(
"%s: Receiver reneged on "
"
data
TSN: 0x%x
\n
"
,
__FUNCTION__
,
tsn
);
tchunk
->
tsn_gap_acked
=
0
;
...
...
@@ -1227,10 +1251,11 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
/* RFC 2960 6.3.2 Retransmission Timer Rules
*
* R4) Whenever a SACK is received missing a TSN
* that was previously acknowledged via a Gap Ack
* Block, start T3-rtx for the destination
* address to which the DATA chunk was originally
* R4) Whenever a SACK is received missing a
* TSN that was previously acknowledged via a
* Gap Ack Block, start T3-rtx for the
* destination address to which the DATA
* chunk was originally
* transmitted if it is not already running.
*/
restart_timer
=
1
;
...
...
@@ -1306,7 +1331,8 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
* active if it is not so marked.
*/
if
(
!
transport
->
state
.
active
)
{
sctp_assoc_control_transport
(
transport
->
asoc
,
sctp_assoc_control_transport
(
transport
->
asoc
,
transport
,
SCTP_TRANSPORT_UP
,
SCTP_RECEIVED_SACK
);
...
...
@@ -1398,8 +1424,7 @@ static void sctp_check_transmitted(sctp_outqueue_t *q,
SCTP_DEBUG_PRINTK
(
"%s: transport: %p, cwnd: %d, "
"ssthresh: %d, flight_size: %d, pba: %d
\n
"
,
__FUNCTION__
,
transport
,
transport
->
cwnd
,
__FUNCTION__
,
transport
,
transport
->
cwnd
,
transport
->
ssthresh
,
transport
->
flight_size
,
transport
->
partial_bytes_acked
);
}
...
...
net/sctp/primitive.c
View file @
dd18325f
net/sctp/protocol.c
View file @
dd18325f
...
...
@@ -66,6 +66,9 @@ struct proc_dir_entry *proc_net_sctp;
*/
static
struct
socket
*
sctp_ctl_socket
;
static
sctp_pf_t
*
sctp_pf_inet6_specific
;
static
sctp_pf_t
*
sctp_pf_inet_specific
;
extern
struct
net_proto_family
inet_family_ops
;
/* Return the address of the control sock. */
...
...
@@ -91,7 +94,7 @@ void sctp_proc_init(void)
void
sctp_proc_exit
(
void
)
{
if
(
proc_net_sctp
)
{
proc_net_sctp
=
NULL
;
proc_net_sctp
=
NULL
;
remove_proc_entry
(
"net/sctp"
,
0
);
}
}
...
...
@@ -135,7 +138,8 @@ static inline void sctp_v4_get_local_addr_list(sctp_protocol_t *proto,
* the protocol structure.
* FIXME: Make this an address family function.
*/
static
inline
void
sctp_v6_get_local_addr_list
(
sctp_protocol_t
*
proto
,
struct
net_device
*
dev
)
static
inline
void
sctp_v6_get_local_addr_list
(
sctp_protocol_t
*
proto
,
struct
net_device
*
dev
)
{
#ifdef SCTP_V6_SUPPORT
/* FIXME: The testframe doesn't support this function. */
...
...
@@ -239,8 +243,7 @@ int sctp_copy_local_addr_list(sctp_protocol_t *proto, sctp_bind_addr_t *bp,
(((
AF_INET6
==
addr
->
a
.
sa
.
sa_family
)
&&
(
copy_flags
&
SCTP_ADDR6_ALLOWED
)
&&
(
copy_flags
&
SCTP_ADDR6_PEERSUPP
))))
{
error
=
sctp_add_bind_addr
(
bp
,
&
addr
->
a
,
error
=
sctp_add_bind_addr
(
bp
,
&
addr
->
a
,
priority
);
if
(
error
)
goto
end_copy
;
...
...
@@ -286,7 +289,8 @@ int sctp_v4_get_dst_mtu(const sockaddr_storage_t *address)
/* Event handler for inet device events.
* Basically, whenever there is an event, we re-build our local address list.
*/
static
int
sctp_netdev_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
static
int
sctp_netdev_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
{
long
flags
__attribute__
((
unused
));
...
...
@@ -347,6 +351,52 @@ sctp_func_t *sctp_get_af_specific(const sockaddr_storage_t *address)
return
retval
;
}
/* Common code to initialize a AF_INET msg_name. */
static
void
sctp_inet_msgname
(
char
*
msgname
,
int
*
addr_len
)
{
struct
sockaddr_in
*
sin
;
sin
=
(
struct
sockaddr_in
*
)
msgname
;
*
addr_len
=
sizeof
(
struct
sockaddr_in
);
sin
->
sin_family
=
AF_INET
;
memset
(
sin
->
sin_zero
,
0
,
sizeof
(
sin
->
sin_zero
));
}
/* Copy the primary address of the peer primary address as the msg_name. */
static
void
sctp_inet_event_msgname
(
sctp_ulpevent_t
*
event
,
char
*
msgname
,
int
*
addr_len
)
{
struct
sockaddr_in
*
sin
,
*
sinfrom
;
if
(
msgname
)
{
sctp_inet_msgname
(
msgname
,
addr_len
);
sin
=
(
struct
sockaddr_in
*
)
msgname
;
sinfrom
=
&
event
->
asoc
->
peer
.
primary_addr
.
v4
;
sin
->
sin_port
=
htons
(
event
->
asoc
->
peer
.
port
);
sin
->
sin_addr
.
s_addr
=
sinfrom
->
sin_addr
.
s_addr
;
}
}
/* Initialize and copy out a msgname from an inbound skb. */
static
void
sctp_inet_skb_msgname
(
struct
sk_buff
*
skb
,
char
*
msgname
,
int
*
addr_len
)
{
struct
sctphdr
*
sh
;
struct
sockaddr_in
*
sin
;
if
(
msgname
)
{
sctp_inet_msgname
(
msgname
,
addr_len
);
sin
=
(
struct
sockaddr_in
*
)
msgname
;
sh
=
(
struct
sctphdr
*
)
skb
->
h
.
raw
;
sin
->
sin_port
=
sh
->
source
;
sin
->
sin_addr
.
s_addr
=
skb
->
nh
.
iph
->
saddr
;
}
}
static
sctp_pf_t
sctp_pf_inet
=
{
.
event_msgname
=
sctp_inet_event_msgname
,
.
skb_msgname
=
sctp_inet_skb_msgname
,
};
/* Registration for netdev events. */
struct
notifier_block
sctp_netdev_notifier
=
{
.
notifier_call
=
sctp_netdev_event
,
...
...
@@ -403,6 +453,34 @@ sctp_func_t sctp_ipv4_specific = {
.
sa_family
=
AF_INET
,
};
sctp_pf_t
*
sctp_get_pf_specific
(
int
family
)
{
switch
(
family
)
{
case
PF_INET
:
return
sctp_pf_inet_specific
;
case
PF_INET6
:
return
sctp_pf_inet6_specific
;
default:
return
NULL
;
}
}
/* Set the PF specific function table. */
void
sctp_set_pf_specific
(
int
family
,
sctp_pf_t
*
pf
)
{
switch
(
family
)
{
case
PF_INET
:
sctp_pf_inet_specific
=
pf
;
break
;
case
PF_INET6
:
sctp_pf_inet6_specific
=
pf
;
break
;
default:
BUG
();
break
;
}
}
/* Initialize the universe into something sensible. */
int
sctp_init
(
void
)
{
...
...
@@ -421,6 +499,8 @@ int sctp_init(void)
/* Initialize object count debugging. */
sctp_dbg_objcnt_init
();
/* Initialize the SCTP specific PF functions. */
sctp_set_pf_specific
(
PF_INET
,
&
sctp_pf_inet
);
/*
* 14. Suggested SCTP Protocol Parameter Values
*/
...
...
@@ -468,7 +548,7 @@ int sctp_init(void)
sctp_proto
.
assoc_hashbucket
=
(
sctp_hashbucket_t
*
)
kmalloc
(
4096
*
sizeof
(
sctp_hashbucket_t
),
GFP_KERNEL
);
if
(
!
sctp_proto
.
assoc_hashbucket
)
{
printk
(
KERN_ERR
"SCTP: Failed association hash alloc.
\n
"
);
printk
(
KERN_ERR
"SCTP: Failed association hash alloc.
\n
"
);
status
=
-
ENOMEM
;
goto
err_ahash_alloc
;
}
...
...
@@ -482,7 +562,7 @@ int sctp_init(void)
sctp_proto
.
ep_hashbucket
=
(
sctp_hashbucket_t
*
)
kmalloc
(
64
*
sizeof
(
sctp_hashbucket_t
),
GFP_KERNEL
);
if
(
!
sctp_proto
.
ep_hashbucket
)
{
printk
(
KERN_ERR
"SCTP: Failed endpoint_hash alloc.
\n
"
);
printk
(
KERN_ERR
"SCTP: Failed endpoint_hash alloc.
\n
"
);
status
=
-
ENOMEM
;
goto
err_ehash_alloc
;
}
...
...
@@ -497,7 +577,7 @@ int sctp_init(void)
sctp_proto
.
port_hashtable
=
(
sctp_bind_hashbucket_t
*
)
kmalloc
(
4096
*
sizeof
(
sctp_bind_hashbucket_t
),
GFP_KERNEL
);
if
(
!
sctp_proto
.
port_hashtable
)
{
printk
(
KERN_ERR
"SCTP: Failed bind hash alloc."
);
printk
(
KERN_ERR
"SCTP: Failed bind hash alloc."
);
status
=
-
ENOMEM
;
goto
err_bhash_alloc
;
}
...
...
net/sctp/sm_make_chunk.c
View file @
dd18325f
...
...
@@ -1418,6 +1418,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
__u8
*
end
;
sctp_transport_t
*
transport
;
struct
list_head
*
pos
,
*
temp
;
char
*
cookie
;
/* We must include the address that the INIT packet came from.
* This is the only address that matters for an INIT packet.
...
...
@@ -1471,6 +1472,15 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
/* Peer Rwnd : Current calculated value of the peer's rwnd. */
asoc
->
peer
.
rwnd
=
asoc
->
peer
.
i
.
a_rwnd
;
/* Copy cookie in case we need to resend COOKIE-ECHO. */
cookie
=
asoc
->
peer
.
cookie
;
if
(
cookie
)
{
asoc
->
peer
.
cookie
=
kmalloc
(
asoc
->
peer
.
cookie_len
,
priority
);
if
(
!
asoc
->
peer
.
cookie
)
goto
clean_up
;
memcpy
(
asoc
->
peer
.
cookie
,
cookie
,
asoc
->
peer
.
cookie_len
);
}
/* RFC 2960 7.2.1 The initial value of ssthresh MAY be arbitrarily
* high (for example, implementations MAY use the size of the receiver
* advertised window).
...
...
@@ -1560,7 +1570,7 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
break
;
case
SCTP_PARAM_HOST_NAME_ADDRESS
:
SCTP_DEBUG_PRINTK
(
"unimplmented SCTP_HOST_NAME_ADDRESS
\n
"
);
SCTP_DEBUG_PRINTK
(
"unimpl
e
mented SCTP_HOST_NAME_ADDRESS
\n
"
);
break
;
case
SCTP_PARAM_SUPPORTED_ADDRESS_TYPES
:
...
...
@@ -1595,13 +1605,12 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
case
SCTP_PARAM_STATE_COOKIE
:
asoc
->
peer
.
cookie_len
=
ntohs
(
param
.
p
->
length
)
-
sizeof
(
sctp_paramhdr_t
);
ntohs
(
param
.
p
->
length
)
-
sizeof
(
sctp_paramhdr_t
);
asoc
->
peer
.
cookie
=
param
.
cookie
->
body
;
break
;
case
SCTP_PARAM_HEATBEAT_INFO
:
SCTP_DEBUG_PRINTK
(
"unimplmented "
SCTP_DEBUG_PRINTK
(
"unimpl
e
mented "
"SCTP_PARAM_HEATBEAT_INFO
\n
"
);
break
;
...
...
net/sctp/sm_sideeffect.c
View file @
dd18325f
...
...
@@ -253,6 +253,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
sctp_chunk_t
*
new_obj
;
sctp_chunk_t
*
chunk
;
sctp_packet_t
*
packet
;
struct
list_head
*
pos
;
struct
timer_list
*
timer
;
unsigned
long
timeout
;
sctp_transport_t
*
t
;
...
...
@@ -336,9 +337,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
case
SCTP_CMD_PEER_INIT
:
/* Process a unified INIT from the peer. */
sctp_cmd_process_init
(
commands
,
asoc
,
chunk
,
command
->
obj
.
ptr
,
priority
);
sctp_cmd_process_init
(
commands
,
asoc
,
chunk
,
command
->
obj
.
ptr
,
priority
);
break
;
case
SCTP_CMD_GEN_COOKIE_ECHO
:
...
...
@@ -462,6 +462,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
break
;
case
SCTP_CMD_INIT_RESTART
:
/* Do the needed accounting and updates
* associated with restarting an initialization
* timer.
...
...
@@ -474,6 +475,15 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
asoc
->
max_init_timeo
;
}
/* If we've sent any data bundled with
* COOKIE-ECHO we need to resend.
*/
list_for_each
(
pos
,
&
asoc
->
peer
.
transport_addr_list
)
{
t
=
list_entry
(
pos
,
sctp_transport_t
,
transports
);
sctp_retransmit_mark
(
&
asoc
->
outqueue
,
t
,
0
);
}
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
SCTP_TO
(
command
->
obj
.
to
));
...
...
@@ -867,6 +877,14 @@ void sctp_generate_t2_shutdown_event(unsigned long data)
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
);
}
void
sctp_generate_t5_shutdown_guard_event
(
unsigned
long
data
)
{
sctp_association_t
*
asoc
=
(
sctp_association_t
*
)
data
;
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
);
}
/* sctp_generate_t5_shutdown_guard_event() */
void
sctp_generate_autoclose_event
(
unsigned
long
data
)
{
sctp_association_t
*
asoc
=
(
sctp_association_t
*
)
data
;
...
...
@@ -932,6 +950,7 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
sctp_generate_t2_shutdown_event
,
NULL
,
NULL
,
sctp_generate_t5_shutdown_guard_event
,
sctp_generate_heartbeat_event
,
sctp_generate_sack_event
,
sctp_generate_autoclose_event
,
...
...
@@ -1023,6 +1042,9 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
event
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
/* FIXME: We need to handle data that could not be sent or was not
* acked, if the user has enabled SEND_FAILED notifications.
*/
...
...
net/sctp/sm_statefuns.c
View file @
dd18325f
...
...
@@ -149,6 +149,9 @@ sctp_disposition_t sctp_sf_do_4_C(const sctp_endpoint_t *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
...
...
@@ -160,35 +163,6 @@ sctp_disposition_t sctp_sf_do_4_C(const sctp_endpoint_t *ep,
return
SCTP_DISPOSITION_NOMEM
;
}
/*
* Discard the whole packet.
*
* Section: 8.4 2)
*
* 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
* silently discard the OOTB packet and take no further action.
* Otherwise,
*
* Verification Tag: No verification necessary
*
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_pdiscard
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
return
SCTP_DISPOSITION_CONSUME
;
}
/*
* Respond to a normal INIT chunk.
* We are the side that is being asked for an association.
...
...
@@ -338,20 +312,17 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep,
if
(
!
reply
)
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
return
SCTP_DISPOSITION_DELETE_TCB
;
}
/* Tag the variable length paramters. Note that we never
* convert the parameters in an INIT chunk.
*/
chunk
->
param_hdr
.
v
=
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_inithdr_t
));
chunk
->
param_hdr
.
v
=
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_inithdr_t
));
initchunk
=
(
sctp_init_chunk_t
*
)
chunk
->
chunk_hdr
;
...
...
@@ -460,8 +431,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const sctp_endpoint_t *ep,
case
-
SCTP_IERROR_BAD_SIG
:
default:
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
};
}
...
...
@@ -625,8 +595,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const sctp_endpoint_t *ep,
if
(
!
reply
)
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
/* Set transport error counter and association error counter
* when sending heartbeat.
...
...
@@ -779,8 +748,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const sctp_endpoint_t *ep,
* sent and mark the destination transport address as active if
* it is not so marked.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSPORT_ON
,
SCTP_TRANSPORT
(
link
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSPORT_ON
,
SCTP_TRANSPORT
(
link
));
return
SCTP_DISPOSITION_CONSUME
;
}
...
...
@@ -875,8 +843,10 @@ static char sctp_tietags_compare(sctp_association_t *new_asoc,
/* Common helper routine for both duplicate and simulataneous INIT
* chunk handling.
*/
static
sctp_disposition_t
sctp_sf_do_unexpected_init
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
static
sctp_disposition_t
sctp_sf_do_unexpected_init
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
chunk
=
arg
;
...
...
@@ -894,8 +864,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep,
chunk
->
subh
.
init_hdr
=
(
sctp_inithdr_t
*
)
chunk
->
skb
->
data
;
/* Tag the variable length parameters. */
chunk
->
param_hdr
.
v
=
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_inithdr_t
));
chunk
->
param_hdr
.
v
=
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_inithdr_t
));
/*
* Other parameters for the endpoint SHOULD be copied from the
...
...
@@ -912,10 +881,9 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep,
* Verification Tag and Peers Verification tag into a reserved
* place (local tie-tag and per tie-tag) within the state cookie.
*/
sctp_process_init
(
new_asoc
,
chunk
->
chunk_hdr
->
type
,
sctp_source
(
chunk
),
(
sctp_init_chunk_t
*
)
chunk
->
chunk_hdr
,
GFP_ATOMIC
);
sctp_process_init
(
new_asoc
,
chunk
->
chunk_hdr
->
type
,
sctp_source
(
chunk
),
(
sctp_init_chunk_t
*
)
chunk
->
chunk_hdr
,
GFP_ATOMIC
);
sctp_tietags_populate
(
new_asoc
,
asoc
);
/* B) "Z" shall respond immediately with an INIT ACK chunk. */
...
...
@@ -1323,10 +1291,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep,
/* "Decode" the chunk. We have no optional parameters so we
* are in good shape.
*/
chunk
->
subh
.
cookie_hdr
=
(
sctp_signed_cookie_t
*
)
chunk
->
skb
->
data
;
skb_pull
(
chunk
->
skb
,
ntohs
(
chunk
->
chunk_hdr
->
length
)
-
sizeof
(
sctp_chunkhdr_t
));
chunk
->
subh
.
cookie_hdr
=
(
sctp_signed_cookie_t
*
)
chunk
->
skb
->
data
;
skb_pull
(
chunk
->
skb
,
ntohs
(
chunk
->
chunk_hdr
->
length
)
-
sizeof
(
sctp_chunkhdr_t
));
/* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
* of a duplicate COOKIE ECHO match the Verification Tags of the
...
...
@@ -1351,8 +1318,7 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep,
case
-
SCTP_IERROR_BAD_SIG
:
default:
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
};
}
...
...
@@ -1398,6 +1364,65 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep,
return
SCTP_DISPOSITION_NOMEM
;
}
/*
* Process an ABORT. (SHUTDOWN-PENDING state)
*
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t
sctp_sf_shutdown_pending_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Stop the T5-shutdown guard timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
return
sctp_sf_do_9_1_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* Process an ABORT. (SHUTDOWN-SENT state)
*
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t
sctp_sf_shutdown_sent_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Stop the T2-shutdown timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
));
/* Stop the T5-shutdown guard timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
return
sctp_sf_do_9_1_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* Process an ABORT. (SHUTDOWN-ACK-SENT state)
*
* See sctp_sf_do_9_1_abort().
*/
sctp_disposition_t
sctp_sf_shutdown_ack_sent_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* The same T2 timer, so we should be able to use
* common function with the SHUTDOWN-SENT state.
*/
return
sctp_sf_shutdown_sent_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
#if 0
/*
* Handle a Stale COOKIE Error
...
...
@@ -1540,11 +1565,8 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const sctp_endpoint_t *ep,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Check the verification tag. */
/* BUG: WRITE ME. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
/* ASSOC_FAILED will DELETE_TCB. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_NULL
());
/* BUG? This does not look complete... */
return
SCTP_DISPOSITION_ABORT
;
...
...
@@ -1561,15 +1583,19 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const sctp_endpoint_t *ep,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Check the verification tag. */
/* BUG: WRITE ME. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T1_INIT
));
/* CMD_INIT_FAILED will DELETE_TCB. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_NULL
());
return
SCTP_DISPOSITION_DELETE_TCB
;
/* BUG? This does not look complete... */
return
SCTP_DISPOSITION_ABORT
;
}
/*
...
...
@@ -1589,67 +1615,6 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const sctp_endpoint_t *ep,
return
sctp_sf_cookie_wait_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
#if 0
/*
* Handle a shutdown timeout or INIT during a shutdown phase.
*
* Section: 9.2
* If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
* (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
* transport addresses (either in the IP addresses or in the INIT chunk)
* that belong to this association, it should discard the INIT chunk and
* retransmit the SHUTDOWN ACK chunk.
*...
* While in SHUTDOWN-SENT state ... If the timer expires, the endpoint
* must re-send the SHUTDOWN ACK.
*
* Verification Tag: Neither the INIT nor the timeout will have a
* valid verification tag, so it is safe to ignore.
*
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t sctp_do_9_2_reshutack(const sctp_endpoint_t *ep,
const sctp_association_t *asoc,
const sctp_subtype_t type,
void *arg,
sctp_cmd_seq_t *commands)
{
sctp_chunk_t *chunk = arg;
/* If this was a timeout (not an INIT), then do the counter
* work. We might need to just dump the association.
*/
if (!chunk) {
if (1 + asoc->counters[SctpCounterRetran] >
asoc->maxRetrans) {
sctp_add_cmd(commands, SCTP_CMD_DELETE_TCB,
SCTP_NULL());
return SCTP_DISPOSITION_DELETE_TCB;
}
retval->counters[0] = SCTP_COUNTER_INCR;
retval->counters[0] = SctpCounterRetran;
retval->counters[1] = 0;
retval->counters[1] = 0;
}
reply = sctp_make_shutdown_ack(asoc, chunk);
if (!reply)
goto nomem;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
return SCTP_DISPOSITION_CONSUME;
nomem:
return SCTP_DISPOSITION_NOMEM;
}
#endif /* 0 */
/*
* sctp_sf_do_9_2_shut
*
...
...
@@ -1694,7 +1659,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep,
sctp_disposition_t
disposition
;
/* Convert the elaborate header. */
sdh
=
(
sctp_shutdownhdr_t
*
)
chunk
->
skb
->
data
;
sdh
=
(
sctp_shutdownhdr_t
*
)
chunk
->
skb
->
data
;
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_shutdownhdr_t
));
chunk
->
subh
.
shutdown_hdr
=
sdh
;
...
...
@@ -1718,8 +1683,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep,
disposition
=
SCTP_DISPOSITION_CONSUME
;
if
(
sctp_outqueue_is_empty
(
&
asoc
->
outqueue
))
{
disposition
=
sctp_sf_do_9_2_shutdown_ack
(
ep
,
asoc
,
type
,
disposition
=
sctp_sf_do_9_2_shutdown_ack
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
...
...
@@ -1732,6 +1696,42 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const sctp_endpoint_t *ep,
return
disposition
;
}
/* RFC 2960 9.2
* If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
* (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
* transport addresses (either in the IP addresses or in the INIT chunk)
* that belong to this association, it should discard the INIT chunk and
* retransmit the SHUTDOWN ACK chunk.
*/
sctp_disposition_t
sctp_sf_do_9_2_reshutack
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
chunk
=
(
sctp_chunk_t
*
)
arg
;
sctp_chunk_t
*
reply
;
reply
=
sctp_make_shutdown_ack
(
asoc
,
chunk
);
if
(
NULL
==
reply
)
goto
nomem
;
/* Set the transport for the SHUTDOWN ACK chunk and the timeout for
* the T2-SHUTDOWN timer.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SETUP_T2
,
SCTP_CHUNK
(
reply
));
/* and restart the T2-shutdown timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
return
SCTP_DISPOSITION_CONSUME
;
nomem:
return
SCTP_DISPOSITION_NOMEM
;
}
/*
* sctp_sf_do_ecn_cwr
*
...
...
@@ -1979,9 +1979,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const sctp_endpoint_t *ep,
* processing the rest of the chunks in the packet.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_NULL
());
return
SCTP_DISPOSITION_CONSUME
;
}
...
...
@@ -2185,9 +2183,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const sctp_endpoint_t *ep,
* processing the rest of the chunks in the packet.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DELETE_TCB
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_NULL
());
return
SCTP_DISPOSITION_CONSUME
;
}
...
...
@@ -2296,14 +2292,12 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const sctp_endpoint_t *ep,
*/
if
(
TSN_lt
(
ctsn
,
asoc
->
ctsn_ack_point
))
{
SCTP_DEBUG_PRINTK
(
"ctsn %x
\n
"
,
ctsn
);
SCTP_DEBUG_PRINTK
(
"ctsn_ack_point %x
\n
"
,
asoc
->
ctsn_ack_point
);
SCTP_DEBUG_PRINTK
(
"ctsn_ack_point %x
\n
"
,
asoc
->
ctsn_ack_point
);
return
SCTP_DISPOSITION_DISCARD
;
}
/* Return this SACK for further processing. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_PROCESS_SACK
,
SCTP_SACKH
(
sackh
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_PROCESS_SACK
,
SCTP_SACKH
(
sackh
));
/* Note: We do the rest of the work on the PROCESS_SACK
* sideeffect.
...
...
@@ -2410,7 +2404,8 @@ sctp_disposition_t sctp_sf_operr_notify(const sctp_endpoint_t *ep,
sctp_ulpevent_t
*
ev
;
while
(
chunk
->
chunk_end
>
chunk
->
skb
->
data
)
{
ev
=
sctp_ulpevent_make_remote_error
(
asoc
,
chunk
,
0
,
GFP_ATOMIC
);
ev
=
sctp_ulpevent_make_remote_error
(
asoc
,
chunk
,
0
,
GFP_ATOMIC
);
if
(
!
ev
)
goto
nomem
;
...
...
@@ -2464,6 +2459,9 @@ sctp_disposition_t sctp_sf_do_9_2_final(const sctp_endpoint_t *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
/* ...send a SHUTDOWN COMPLETE chunk to its peer, */
reply
=
sctp_make_shutdown_complete
(
asoc
,
chunk
);
if
(
!
reply
)
...
...
@@ -2616,6 +2614,148 @@ sctp_disposition_t sctp_sf_shut_8_4_5(const sctp_endpoint_t *ep,
nomem:
return
SCTP_DISPOSITION_NOMEM
;
}
/*
* Process an unknown chunk.
*
* Section: 3.2. Also, 2.1 in the implementor's guide.
*
* Chunk Types are encoded such that the highest-order two bits specify
* the action that must be taken if the processing endpoint does not
* recognize the Chunk Type.
*
* 00 - Stop processing this SCTP packet and discard it, do not process
* any further chunks within it.
*
* 01 - Stop processing this SCTP packet and discard it, do not process
* any further chunks within it, and report the unrecognized
* chunk in an 'Unrecognized Chunk Type'.
*
* 10 - Skip this chunk and continue processing.
*
* 11 - Skip this chunk and continue processing, but report in an ERROR
* Chunk using the 'Unrecognized Chunk Type' cause of error.
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_unk_chunk
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
unk_chunk
=
arg
;
sctp_chunk_t
*
err_chunk
;
sctp_chunkhdr_t
*
hdr
;
SCTP_DEBUG_PRINTK
(
"Processing the unknown chunk id %d.
\n
"
,
type
.
chunk
);
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
* that the value in the Verification Tag field of the
* received SCTP packet matches its own Tag. If the received
* Verification Tag value does not match the receiver's own
* tag value, the receiver shall silently discard the packet.
*/
if
(
ntohl
(
unk_chunk
->
sctp_hdr
->
vtag
)
!=
asoc
->
c
.
my_vtag
)
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
switch
(
type
.
chunk
&
SCTP_CID_ACTION_MASK
)
{
case
SCTP_CID_ACTION_DISCARD
:
/* Discard the packet. */
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
break
;
case
SCTP_CID_ACTION_DISCARD_ERR
:
/* Discard the packet. */
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
/* Generate an ERROR chunk as response. */
hdr
=
unk_chunk
->
chunk_hdr
;
err_chunk
=
sctp_make_op_error
(
asoc
,
unk_chunk
,
SCTP_ERROR_UNKNOWN_CHUNK
,
hdr
,
WORD_ROUND
(
ntohs
(
hdr
->
length
)));
if
(
err_chunk
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
err_chunk
));
}
return
SCTP_DISPOSITION_CONSUME
;
break
;
case
SCTP_CID_ACTION_SKIP
:
/* Skip the chunk. */
return
SCTP_DISPOSITION_DISCARD
;
break
;
case
SCTP_CID_ACTION_SKIP_ERR
:
/* Generate an ERROR chunk as response. */
hdr
=
unk_chunk
->
chunk_hdr
;
err_chunk
=
sctp_make_op_error
(
asoc
,
unk_chunk
,
SCTP_ERROR_UNKNOWN_CHUNK
,
hdr
,
WORD_ROUND
(
ntohs
(
hdr
->
length
)));
if
(
err_chunk
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
err_chunk
));
}
/* Skip the chunk. */
return
SCTP_DISPOSITION_CONSUME
;
break
;
default:
break
;
}
return
SCTP_DISPOSITION_DISCARD
;
}
/*
* Discard the chunk.
*
* Section: 0.2, 5.2.3, 5.2.5, 5.2.6, 6.0, 8.4.6, 8.5.1c, 9.2
* [Too numerous to mention...]
* Verification Tag: No verification needed.
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_discard_chunk
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
SCTP_DEBUG_PRINTK
(
"Chunk %d is discarded
\n
"
,
type
.
chunk
);
return
SCTP_DISPOSITION_DISCARD
;
}
/*
* Discard the whole packet.
*
* Section: 8.4 2)
*
* 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
* silently discard the OOTB packet and take no further action.
* Otherwise,
*
* Verification Tag: No verification necessary
*
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_pdiscard
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
return
SCTP_DISPOSITION_CONSUME
;
}
#if 0
/*
...
...
@@ -2976,10 +3116,16 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(const sctp_endpoint_t *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_SHUTDOWN_PENDING
));
/* sctpimpguide-05 Section 2.12.2
* The sender of the SHUTDOWN MAY also start an overall guard timer
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_START
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
disposition
=
SCTP_DISPOSITION_CONSUME
;
if
(
sctp_outqueue_is_empty
(
&
asoc
->
outqueue
))
{
disposition
=
sctp_sf_do_9_2_start_shutdown
(
ep
,
asoc
,
type
,
disposition
=
sctp_sf_do_9_2_start_shutdown
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
return
disposition
;
...
...
@@ -3042,12 +3188,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(const sctp_endpoint_t *ep,
* TCB. This is a departure from our typical NOMEM handling.
*/
/* Change to CLOSED state. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
/* Delete the established association. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_
DELETE_TCB
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_
ASSOC_FAILED
,
SCTP_NULL
());
return
retval
;
}
...
...
@@ -3090,7 +3232,8 @@ sctp_disposition_t sctp_sf_error_shutdown(const sctp_endpoint_t *ep,
* Outputs
* (timers)
*/
sctp_disposition_t
sctp_sf_cookie_wait_prm_shutdown
(
const
sctp_endpoint_t
*
ep
,
sctp_disposition_t
sctp_sf_cookie_wait_prm_shutdown
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
...
...
@@ -3134,7 +3277,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown(
}
/*
* sctp_cookie_wait_prm_abort
* sctp_
sf_
cookie_wait_prm_abort
*
* Section: 4 Note: 2
* Verification Tag:
...
...
@@ -3153,14 +3296,36 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(const sctp_endpoint_t *ep,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
abort
;
sctp_disposition_t
retval
;
/* Stop T1-init timer */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T1_INIT
));
return
sctp_sf_do_9_1_prm_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
retval
=
SCTP_DISPOSITION_CONSUME
;
/* Generate ABORT chunk to send the peer */
abort
=
sctp_make_abort
(
asoc
,
NULL
,
0
);
if
(
!
abort
)
retval
=
SCTP_DISPOSITION_NOMEM
;
else
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
abort
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_CLOSED
));
/* Even if we can't send the ABORT due to low memory delete the
* TCB. This is a departure from our typical NOMEM handling.
*/
/* Delete the established association. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_NULL
());
return
retval
;
}
/*
* sctp_cookie_echoed_prm_abort
* sctp_
sf_
cookie_echoed_prm_abort
*
* Section: 4 Note: 3
* Verification Tag:
...
...
@@ -3185,6 +3350,87 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(const sctp_endpoint_t *ep,
return
sctp_sf_cookie_wait_prm_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* sctp_sf_shutdown_pending_prm_abort
*
* Inputs
* (endpoint, asoc)
*
* The RFC does not explicitly address this issue, but is the route through the
* state table when someone issues an abort while in SHUTDOWN-PENDING state.
*
* Outputs
* (timers)
*/
sctp_disposition_t
sctp_sf_shutdown_pending_prm_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Stop the T5-shutdown guard timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
return
sctp_sf_do_9_1_prm_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* sctp_sf_shutdown_sent_prm_abort
*
* Inputs
* (endpoint, asoc)
*
* The RFC does not explicitly address this issue, but is the route through the
* state table when someone issues an abort while in SHUTDOWN-SENT state.
*
* Outputs
* (timers)
*/
sctp_disposition_t
sctp_sf_shutdown_sent_prm_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* Stop the T2-shutdown timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
));
/* Stop the T5-shutdown guard timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
return
sctp_sf_do_9_1_prm_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* sctp_sf_cookie_echoed_prm_abort
*
* Inputs
* (endpoint, asoc)
*
* The RFC does not explcitly address this issue, but is the route through the
* state table when someone issues an abort while in COOKIE_ECHOED state.
*
* Outputs
* (timers)
*/
sctp_disposition_t
sctp_sf_shutdown_ack_sent_prm_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* The same T2 timer, so we should be able to use
* common function with the SHUTDOWN-SENT state.
*/
return
sctp_sf_shutdown_sent_prm_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
* Ignore the primitive event
*
...
...
@@ -3322,8 +3568,7 @@ sctp_disposition_t sctp_sf_ignore_other(const sctp_endpoint_t *ep,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
SCTP_DEBUG_PRINTK
(
"The event other type %d is ignored
\n
"
,
type
.
other
);
SCTP_DEBUG_PRINTK
(
"The event other type %d is ignored
\n
"
,
type
.
other
);
return
SCTP_DISPOSITION_DISCARD
;
}
...
...
@@ -3479,11 +3724,11 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const sctp_endpoint_t *ep,
if
(
!
repl
)
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
/* Issue a sideeffect to do the needed accounting. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_RESTART
,
SCTP_TO
(
timer
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
}
else
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_NULL
());
return
SCTP_DISPOSITION_DELETE_TCB
;
...
...
@@ -3559,6 +3804,34 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const sctp_endpoint_t *ep,
return
SCTP_DISPOSITION_NOMEM
;
}
/* sctpimpguide-05 Section 2.12.2
* The sender of the SHUTDOWN MAY also start an overall guard timer
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
* At the expiration of this timer the sender SHOULD abort the association
* by sending an ABORT chunk.
*/
sctp_disposition_t
sctp_sf_t5_timer_expire
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
reply
=
NULL
;
SCTP_DEBUG_PRINTK
(
"Timer T5 expired.
\n
"
);
reply
=
sctp_make_abort
(
asoc
,
NULL
,
0
);
if
(
!
reply
)
goto
nomem
;
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
reply
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_NULL
());
return
SCTP_DISPOSITION_DELETE_TCB
;
nomem:
return
SCTP_DISPOSITION_NOMEM
;
}
/* Handle expiration of AUTOCLOSE timer. When the autoclose timer expires,
* the association is automatically closed by starting the shutdown process.
* The work that needs to be done is same as when SHUTDOWN is initiated by
...
...
@@ -3583,10 +3856,15 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire(const sctp_endpoint_t *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_SHUTDOWN_PENDING
));
/* sctpimpguide-05 Section 2.12.2
* The sender of the SHUTDOWN MAY also start an overall guard timer
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_START
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
));
disposition
=
SCTP_DISPOSITION_CONSUME
;
if
(
sctp_outqueue_is_empty
(
&
asoc
->
outqueue
))
{
disposition
=
sctp_sf_do_9_2_start_shutdown
(
ep
,
asoc
,
type
,
disposition
=
sctp_sf_do_9_2_start_shutdown
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
return
disposition
;
...
...
@@ -3651,30 +3929,6 @@ sctp_disposition_t sctp_sf_timer_ignore(const sctp_endpoint_t *ep,
return
SCTP_DISPOSITION_CONSUME
;
}
/*
* Discard the chunk.
*
* Section: 0.2, 5.2.3, 5.2.5, 5.2.6, 6.0, 8.4.6, 8.5.1c, 9.2
* [Too numerous to mention...]
* Verification Tag: No verification needed.
* Inputs
* (endpoint, asoc, chunk)
*
* Outputs
* (asoc, reply_msg, msg_up, timers, counters)
*
* The return value is the disposition of the chunk.
*/
sctp_disposition_t
sctp_sf_discard_chunk
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
SCTP_DEBUG_PRINTK
(
"Chunk %d is discarded
\n
"
,
type
.
chunk
);
return
SCTP_DISPOSITION_DISCARD
;
}
/********************************************************************
* 2nd Level Abstractions
********************************************************************/
...
...
net/sctp/sm_statetable.c
View file @
dd18325f
...
...
@@ -48,9 +48,10 @@
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
sctp_sm_table_entry_t
nop
=
{
fn
:
sctp_sf_discard_chunk
,
name:
"sctp_sf_discard_chunk"
};
sctp_sm_table_entry_t
bug
=
{
fn
:
sctp_sf_bug
,
name
:
"sctp_sf_bug"
};
sctp_sm_table_entry_t
bug
=
{
.
fn
=
sctp_sf_bug
,
.
name
=
"sctp_sf_bug"
};
#define DO_LOOKUP(_max, _type, _table) \
if ((event_subtype._type > (_max))) { \
...
...
@@ -58,9 +59,9 @@ sctp_sm_table_entry_t bug = {fn: sctp_sf_bug, name: "sctp_sf_bug"};
"sctp table %p possible attack:" \
" event %d exceeds max %d\n", \
_table, event_subtype._type, _max); \
return
(&bug)
; \
return
&bug
; \
} \
return
(&_table[event_subtype._type][(int)state])
;
return
&_table[event_subtype._type][(int)state]
;
sctp_sm_table_entry_t
*
sctp_sm_lookup_event
(
sctp_event_t
event_type
,
sctp_state_t
state
,
...
...
@@ -92,320 +93,323 @@ sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
#define TYPE_SCTP_DATA { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_eat_data_6_2, name:
"sctp_sf_eat_data_6_2"}, \
{
.fn = sctp_sf_eat_data_6_2, .name =
"sctp_sf_eat_data_6_2"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_eat_data_6_2, name:
"sctp_sf_eat_data_6_2"}, \
{
.fn = sctp_sf_eat_data_6_2, .name =
"sctp_sf_eat_data_6_2"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_eat_data_fast_4_4, name:
"sctp_sf_eat_data_fast_4_4"}, \
{
.fn = sctp_sf_eat_data_fast_4_4, .name =
"sctp_sf_eat_data_fast_4_4"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.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"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_DATA */
#define TYPE_SCTP_INIT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_do_5_1B_init, name:
"sctp_sf_do_5_1B_init"}, \
{
.fn = sctp_sf_do_5_1B_init, .name =
"sctp_sf_do_5_1B_init"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_do_5_2_1_siminit, name:
"sctp_sf_do_5_2_1_siminit"}, \
{
.fn = sctp_sf_do_5_2_1_siminit, .name =
"sctp_sf_do_5_2_1_siminit"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_5_2_1_siminit, name:
"sctp_sf_do_5_2_1_siminit"}, \
{
.fn = sctp_sf_do_5_2_1_siminit, .name =
"sctp_sf_do_5_2_1_siminit"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_5_2_2_dupinit, name:
"sctp_sf_do_5_2_2_dupinit"}, \
{
.fn = sctp_sf_do_5_2_2_dupinit, .name =
"sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_5_2_2_dupinit, name:
"sctp_sf_do_5_2_2_dupinit"}, \
{
.fn = sctp_sf_do_5_2_2_dupinit, .name =
"sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_5_2_2_dupinit, name:
"sctp_sf_do_5_2_2_dupinit"}, \
{
.fn = sctp_sf_do_5_2_2_dupinit, .name =
"sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_do_5_2_2_dupinit, name:
"sctp_sf_do_5_2_2_dupinit"}, \
{
.fn = sctp_sf_do_5_2_2_dupinit, .name =
"sctp_sf_do_5_2_2_dupinit"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_do_9_2_reshutack, .name = "sctp_sf_do_9_2_reshutack
"}, \
}
/* TYPE_SCTP_INIT */
#define TYPE_SCTP_INIT_ACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_do_5_1C_ack, name:
"sctp_sf_do_5_1C_ack"}, \
{
.fn = sctp_sf_do_5_1C_ack, .name =
"sctp_sf_do_5_1C_ack"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.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"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_INIT_ACK */
#define TYPE_SCTP_SACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_eat_sack_6_2, name:
"sctp_sf_eat_sack_6_2"}, \
{
.fn = sctp_sf_eat_sack_6_2, .name =
"sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_eat_sack_6_2, name:
"sctp_sf_eat_sack_6_2"}, \
{
.fn = sctp_sf_eat_sack_6_2, .name =
"sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_eat_sack_6_2, name:
"sctp_sf_eat_sack_6_2"}, \
{
.fn = sctp_sf_eat_sack_6_2, .name =
"sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_eat_sack_6_2, name:
"sctp_sf_eat_sack_6_2"}, \
{
.fn = sctp_sf_eat_sack_6_2, .name =
"sctp_sf_eat_sack_6_2"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_SACK */
#define TYPE_SCTP_HEARTBEAT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
/* This should not happen, but we are nice. */
\
{
fn: sctp_sf_beat_8_3, name:
"sctp_sf_beat_8_3"}, \
{
.fn = sctp_sf_beat_8_3, .name =
"sctp_sf_beat_8_3"}, \
}
/* TYPE_SCTP_HEARTBEAT */
#define TYPE_SCTP_HEARTBEAT_ACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_violation, name:
"sctp_sf_violation"}, \
{
.fn = sctp_sf_violation, .name =
"sctp_sf_violation"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_backbeat_8_3, name:
"sctp_sf_backbeat_8_3"}, \
{
.fn = sctp_sf_backbeat_8_3, .name =
"sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_backbeat_8_3, name:
"sctp_sf_backbeat_8_3"}, \
{
.fn = sctp_sf_backbeat_8_3, .name =
"sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_backbeat_8_3, name:
"sctp_sf_backbeat_8_3"}, \
{
.fn = sctp_sf_backbeat_8_3, .name =
"sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_backbeat_8_3, name:
"sctp_sf_backbeat_8_3"}, \
{
.fn = sctp_sf_backbeat_8_3, .name =
"sctp_sf_backbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_HEARTBEAT_ACK */
#define TYPE_SCTP_ABORT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_pdiscard, name:
"sctp_sf_pdiscard"}, \
{
.fn = sctp_sf_pdiscard, .name =
"sctp_sf_pdiscard"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_cookie_wait_abort, name:
"sctp_sf_cookie_wait_abort"}, \
{
.fn = sctp_sf_cookie_wait_abort, .name =
"sctp_sf_cookie_wait_abort"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn:
sctp_sf_cookie_echoed_abort, \
name:
"sctp_sf_cookie_echoed_abort"}, \
{
.fn =
sctp_sf_cookie_echoed_abort, \
.name =
"sctp_sf_cookie_echoed_abort"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_9_1_abort, name:
"sctp_sf_do_9_1_abort"}, \
{
.fn = sctp_sf_do_9_1_abort, .name =
"sctp_sf_do_9_1_abort"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
{.fn = sctp_sf_shutdown_pending_abort, \
.name = "sctp_sf_shutdown_pending_abort"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
{.fn = sctp_sf_shutdown_sent_abort, \
.name = "sctp_sf_shutdown_sent_abort"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_do_9_1_abort, name:
"sctp_sf_do_9_1_abort"}, \
{
.fn = sctp_sf_do_9_1_abort, .name =
"sctp_sf_do_9_1_abort"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{fn: sctp_sf_do_9_1_abort, name: "sctp_sf_do_9_1_abort"}, \
{.fn = sctp_sf_shutdown_ack_sent_abort, \
.name = "sctp_sf_shutdown_ack_sent_abort"}, \
}
/* TYPE_SCTP_ABORT */
#define TYPE_SCTP_SHUTDOWN { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_9_2_shutdown, name:
"sctp_sf_do_9_2_shutdown"}, \
{
.fn = sctp_sf_do_9_2_shutdown, .name =
"sctp_sf_do_9_2_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn:
sctp_sf_do_9_2_shutdown_ack, \
name:
"sctp_sf_do_9_2_shutdown_ack"}, \
{
.fn =
sctp_sf_do_9_2_shutdown_ack, \
.name =
"sctp_sf_do_9_2_shutdown_ack"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.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"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_SHUTDOWN */
#define TYPE_SCTP_SHUTDOWN_ACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_ootb, .name = "sctp_sf_ootb
"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_ootb, .name = "sctp_sf_ootb
"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_violation, name:
"sctp_sf_violation"}, \
{
.fn = sctp_sf_violation, .name =
"sctp_sf_violation"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_violation, name:
"sctp_sf_violation"}, \
{
.fn = sctp_sf_violation, .name =
"sctp_sf_violation"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_9_2_final, name:
"sctp_sf_do_9_2_final"}, \
{
.fn = sctp_sf_do_9_2_final, .name =
"sctp_sf_do_9_2_final"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_violation, name:
"sctp_sf_violation"}, \
{
.fn = sctp_sf_violation, .name =
"sctp_sf_violation"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_do_9_2_final, name:
"sctp_sf_do_9_2_final"}, \
{
.fn = sctp_sf_do_9_2_final, .name =
"sctp_sf_do_9_2_final"}, \
}
/* TYPE_SCTP_SHUTDOWN_ACK */
#define TYPE_SCTP_ERROR { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_tabort_8_4_8, name:
"sctp_sf_tabort_8_4_8"}, \
{
.fn = sctp_sf_tabort_8_4_8, .name =
"sctp_sf_tabort_8_4_8"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_operr_notify, name:
"sctp_sf_operr_notify"}, \
{
.fn = sctp_sf_operr_notify, .name =
"sctp_sf_operr_notify"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_ERROR */
#define TYPE_SCTP_COOKIE_ECHO { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_do_5_1D_ce, name:
"sctp_sf_do_5_1D_ce"}, \
{
.fn = sctp_sf_do_5_1D_ce, .name =
"sctp_sf_do_5_1D_ce"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_do_5_2_4_dupcook, name:
"sctp_sf_do_5_2_4_dupcook"}, \
{
.fn = sctp_sf_do_5_2_4_dupcook, .name =
"sctp_sf_do_5_2_4_dupcook"}, \
}
/* TYPE_SCTP_COOKIE_ECHO */
#define TYPE_SCTP_COOKIE_ACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_5_1E_ca, name:
"sctp_sf_do_5_1E_ca"}, \
{
.fn = sctp_sf_do_5_1E_ca, .name =
"sctp_sf_do_5_1E_ca"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.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"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
}
/* TYPE_SCTP_COOKIE_ACK */
#define TYPE_SCTP_ECN_ECNE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_ecne, name:
"sctp_sf_do_ecne"}, \
{
.fn = sctp_sf_do_ecne, .name =
"sctp_sf_do_ecne"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_ecne, name:
"sctp_sf_do_ecne"}, \
{
.fn = sctp_sf_do_ecne, .name =
"sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_ecne, name:
"sctp_sf_do_ecne"}, \
{
.fn = sctp_sf_do_ecne, .name =
"sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_ecne, name:
"sctp_sf_do_ecne"}, \
{
.fn = sctp_sf_do_ecne, .name =
"sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_do_ecne, name:
"sctp_sf_do_ecne"}, \
{
.fn = sctp_sf_do_ecne, .name =
"sctp_sf_do_ecne"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
}
/* TYPE_SCTP_ECN_ECNE */
#define TYPE_SCTP_ECN_CWR { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_ecn_cwr, name:
"sctp_sf_do_ecn_cwr"}, \
{
.fn = sctp_sf_do_ecn_cwr, .name =
"sctp_sf_do_ecn_cwr"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_ecn_cwr, name:
"sctp_sf_do_ecn_cwr"}, \
{
.fn = sctp_sf_do_ecn_cwr, .name =
"sctp_sf_do_ecn_cwr"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_ecn_cwr, name:
"sctp_sf_do_ecn_cwr"}, \
{
.fn = sctp_sf_do_ecn_cwr, .name =
"sctp_sf_do_ecn_cwr"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
}
/* TYPE_SCTP_ECN_CWR */
#define TYPE_SCTP_SHUTDOWN_COMPLETE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_ootb, name:
"sctp_sf_ootb"}, \
{
.fn = sctp_sf_ootb, .name =
"sctp_sf_ootb"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_discard_chunk, name:
"sctp_sf_discard_chunk"}, \
{
.fn = sctp_sf_discard_chunk, .name =
"sctp_sf_discard_chunk"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_do_4_C, name:
"sctp_sf_do_4_C"}, \
{
.fn = sctp_sf_do_4_C, .name =
"sctp_sf_do_4_C"}, \
}
/* TYPE_SCTP_SHUTDOWN_COMPLETE */
/* The primary index for this table is the chunk type.
...
...
@@ -434,397 +438,415 @@ sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NU
static
sctp_sm_table_entry_t
chunk_event_table_asconf
[
SCTP_STATE_NUM_STATES
]
=
{
/* SCTP_STATE_EMPTY */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_CLOSED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_WAIT */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_ECHOED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_ESTABLISHED */
{
fn
:
sctp_sf_discard_chunk
,
name:
"sctp_sf_discard_chunk (will be sctp_addip_do_asconf)"
},
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk (will be sctp_addip_do_asconf)"
},
/* SCTP_STATE_SHUTDOWN_PENDING */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_SENT */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_RECEIVED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
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"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
};
/* chunk asconf */
static
sctp_sm_table_entry_t
chunk_event_table_asconf_ack
[
SCTP_STATE_NUM_STATES
]
=
{
/* SCTP_STATE_EMPTY */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_CLOSED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_WAIT */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_ECHOED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_ESTABLISHED */
{
fn
:
sctp_sf_discard_chunk
,
name:
"sctp_sf_discard_chunk (will be sctp_addip_do_asconf_ack)"
},
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk (will be sctp_addip_do_asconf_ack)"
},
/* SCTP_STATE_SHUTDOWN_PENDING */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_SENT */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_RECEIVED */
{
fn
:
sctp_sf_discard_chunk
,
name
:
"sctp_sf_discard_chunk"
},
{
.
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"
},
{
.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
};
/* chunk asconf_ack */
static
sctp_sm_table_entry_t
chunk_event_table_unknown
[
SCTP_STATE_NUM_STATES
]
=
{
/* SCTP_STATE_EMPTY */
{.
fn
=
sctp_sf_ootb
,
.
name
=
"sctp_sf_ootb"
},
/* SCTP_STATE_CLOSED */
{.
fn
=
sctp_sf_tabort_8_4_8
,
.
name
=
"sctp_sf_tabort_8_4_8"
},
/* SCTP_STATE_COOKIE_WAIT */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_COOKIE_ECHOED */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_ESTABLISHED */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_SHUTDOWN_PENDING */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_SHUTDOWN_SENT */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_SHUTDOWN_RECEIVED */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
{.
fn
=
sctp_sf_unk_chunk
,
.
name
=
"sctp_sf_unk_chunk"
},
};
/* chunk unknown */
#define TYPE_SCTP_PRIMITIVE_INITIALIZE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_INITIALIZE */
#define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_do_prm_asoc, name:
"sctp_sf_do_prm_asoc"}, \
{
.fn = sctp_sf_do_prm_asoc, .name =
"sctp_sf_do_prm_asoc"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_ASSOCIATE */
#define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_error_closed, name:
"sctp_sf_error_closed"}, \
{
.fn = sctp_sf_error_closed, .name =
"sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn:
sctp_sf_cookie_wait_prm_shutdown, \
name:
"sctp_sf_cookie_wait_prm_shutdown"}, \
{
.fn =
sctp_sf_cookie_wait_prm_shutdown, \
.name =
"sctp_sf_cookie_wait_prm_shutdown"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn:
sctp_sf_cookie_echoed_prm_shutdown, \
{
.fn =
sctp_sf_cookie_echoed_prm_shutdown, \
name:"sctp_sf_cookie_echoed_prm_shutdown"},\
/* SCTP_STATE_ESTABLISHED */
\
{
fn:
sctp_sf_do_9_2_prm_shutdown, \
name:
"sctp_sf_do_9_2_prm_shutdown"}, \
{
.fn =
sctp_sf_do_9_2_prm_shutdown, \
.name =
"sctp_sf_do_9_2_prm_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_ignore_primitive, name:
"sctp_sf_ignore_primitive"}, \
{
.fn = sctp_sf_ignore_primitive, .name =
"sctp_sf_ignore_primitive"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_ignore_primitive, name:
"sctp_sf_ignore_primitive"}, \
{
.fn = sctp_sf_ignore_primitive, .name =
"sctp_sf_ignore_primitive"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_ignore_primitive, name:
"sctp_sf_ignore_primitive"}, \
{
.fn = sctp_sf_ignore_primitive, .name =
"sctp_sf_ignore_primitive"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_ignore_primitive, name:
"sctp_sf_ignore_primitive"}, \
{
.fn = sctp_sf_ignore_primitive, .name =
"sctp_sf_ignore_primitive"}, \
}
/* TYPE_SCTP_PRIMITIVE_SHUTDOWN */
#define TYPE_SCTP_PRIMITIVE_ABORT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_error_closed, name:
"sctp_sf_error_closed"}, \
{
.fn = sctp_sf_error_closed, .name =
"sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn:
sctp_sf_cookie_wait_prm_abort, \
name:
"sctp_sf_cookie_wait_prm_abort"}, \
{
.fn =
sctp_sf_cookie_wait_prm_abort, \
.name =
"sctp_sf_cookie_wait_prm_abort"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn:
sctp_sf_cookie_echoed_prm_abort, \
name:
"sctp_sf_cookie_echoed_prm_abort"}, \
{
.fn =
sctp_sf_cookie_echoed_prm_abort, \
.name =
"sctp_sf_cookie_echoed_prm_abort"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn:
sctp_sf_do_9_1_prm_abort, \
name:
"sctp_sf_do_9_1_prm_abort"}, \
{
.fn =
sctp_sf_do_9_1_prm_abort, \
.name =
"sctp_sf_do_9_1_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_9_1
_prm_abort, \
name: "sctp_sf_do_9_1
_prm_abort"}, \
{
.fn = sctp_sf_shutdown_pending
_prm_abort, \
.name = "sctp_sf_shutdown_pending
_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_9_1
_prm_abort, \
name: "sctp_sf_do_9_1
_prm_abort"}, \
{
.fn = sctp_sf_shutdown_sent
_prm_abort, \
.name = "sctp_sf_shutdown_sent
_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn:
sctp_sf_do_9_1_prm_abort, \
name:
"sctp_sf_do_9_1_prm_abort"}, \
{
.fn =
sctp_sf_do_9_1_prm_abort, \
.name =
"sctp_sf_do_9_1_prm_abort"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_do_9_1
_prm_abort, \
name: "sctp_sf_do_9_1
_prm_abort"}, \
{
.fn = sctp_sf_shutdown_ack_sent
_prm_abort, \
.name = "sctp_sf_shutdown_ack_sent
_prm_abort"}, \
}
/* TYPE_SCTP_PRIMITIVE_ABORT */
#define TYPE_SCTP_PRIMITIVE_SEND { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_error_closed, name:
"sctp_sf_error_closed"}, \
{
.fn = sctp_sf_error_closed, .name =
"sctp_sf_error_closed"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_do_prm_send, name:
"sctp_sf_do_prm_send"}, \
{
.fn = sctp_sf_do_prm_send, .name =
"sctp_sf_do_prm_send"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_prm_send, name:
"sctp_sf_do_prm_send"}, \
{
.fn = sctp_sf_do_prm_send, .name =
"sctp_sf_do_prm_send"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_prm_send, name:
"sctp_sf_do_prm_send"}, \
{
.fn = sctp_sf_do_prm_send, .name =
"sctp_sf_do_prm_send"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_error_shutdown, name:
"sctp_sf_error_shutdown"}, \
{
.fn = sctp_sf_error_shutdown, .name =
"sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_error_shutdown, name:
"sctp_sf_error_shutdown"}, \
{
.fn = sctp_sf_error_shutdown, .name =
"sctp_sf_error_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_error_shutdown, name:
"sctp_sf_error_shutdown"}, \
{
.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"}, \
{
.fn = sctp_sf_error_shutdown, .name =
"sctp_sf_error_shutdown"}, \
}
/* TYPE_SCTP_PRIMITIVE_SEND */
#define TYPE_SCTP_PRIMITIVE_SETPRIMARY { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_SETPRIMARY */
#define TYPE_SCTP_PRIMITIVE_RECEIVE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_RECEIVE */
#define TYPE_SCTP_PRIMITIVE_STATUS { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_STATUS */
#define TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT */
#define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
#define TYPE_SCTP_PRIMITIVE_GETSRTTREPORT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_GETSRTTREPORT */
#define TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD */
#define TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS */
#define TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT */
#define TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED */
#define TYPE_SCTP_PRIMITIVE_DESTROY { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
/* TYPE_SCTP_PRIMITIVE_DESTROY */
/* The primary index for this table is the primitive type.
...
...
@@ -851,46 +873,46 @@ sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE
#define TYPE_SCTP_OTHER_NO_PENDING_TSN { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn:
sctp_sf_do_9_2_start_shutdown, \
name:
"sctp_do_9_2_start_shutdown"}, \
{
.fn =
sctp_sf_do_9_2_start_shutdown, \
.name =
"sctp_do_9_2_start_shutdown"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn:
sctp_sf_do_9_2_shutdown_ack, \
name:
"sctp_sf_do_9_2_shutdown_ack"}, \
{
.fn =
sctp_sf_do_9_2_shutdown_ack, \
.name =
"sctp_sf_do_9_2_shutdown_ack"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_ignore_other, name:
"sctp_sf_ignore_other"}, \
{
.fn = sctp_sf_ignore_other, .name =
"sctp_sf_ignore_other"}, \
}
#define TYPE_SCTP_OTHER_ICMP_UNREACHFRAG { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
sctp_sm_table_entry_t
other_event_table
[
SCTP_NUM_OTHER_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
...
...
@@ -900,213 +922,234 @@ sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STA
#define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_t1_timer_expire, name:
"sctp_sf_t1_timer_expire"}, \
{
.fn = sctp_sf_t1_timer_expire, .name =
"sctp_sf_t1_timer_expire"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.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"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_t1_timer_expire, name:
"sctp_sf_t1_timer_expire"}, \
{
.fn = sctp_sf_t1_timer_expire, .name =
"sctp_sf_t1_timer_expire"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.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"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_t2_timer_expire, name:
"sctp_sf_t2_timer_expire"}, \
{
.fn = sctp_sf_t2_timer_expire, .name =
"sctp_sf_t2_timer_expire"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_t2_timer_expire, name:
"sctp_sf_t2_timer_expire"}, \
{
.fn = sctp_sf_t2_timer_expire, .name =
"sctp_sf_t2_timer_expire"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_do_6_3_3_rtx, name:
"sctp_sf_do_6_3_3_rtx"}, \
{
.fn = sctp_sf_do_6_3_3_rtx, .name =
"sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_6_3_3_rtx, name:
"sctp_sf_do_6_3_3_rtx"}, \
{
.fn = sctp_sf_do_6_3_3_rtx, .name =
"sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_6_3_3_rtx, name:
"sctp_sf_do_6_3_3_rtx"}, \
{
.fn = sctp_sf_do_6_3_3_rtx, .name =
"sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_do_6_3_3_rtx, name:
"sctp_sf_do_6_3_3_rtx"}, \
{
.fn = sctp_sf_do_6_3_3_rtx, .name =
"sctp_sf_do_6_3_3_rtx"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
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_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{fn: sctp_sf_not_impl, name: "sctp_sf_not_impl"}, \
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \
/* 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_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{.fn = sctp_sf_t5_timer_expire, .name = "sctp_sf_t5_timer_expire"}, \
/* 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_HEARTBEAT { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_sendbeat_8_3, name:
"sctp_sf_sendbeat_8_3"}, \
{
.fn = sctp_sf_sendbeat_8_3, .name =
"sctp_sf_sendbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_sendbeat_8_3, name:
"sctp_sf_sendbeat_8_3"}, \
{
.fn = sctp_sf_sendbeat_8_3, .name =
"sctp_sf_sendbeat_8_3"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_SACK { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_do_6_2_sack, name:
"sctp_sf_do_6_2_sack"}, \
{
.fn = sctp_sf_do_6_2_sack, .name =
"sctp_sf_do_6_2_sack"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_do_6_2_sack, name:
"sctp_sf_do_6_2_sack"}, \
{
.fn = sctp_sf_do_6_2_sack, .name =
"sctp_sf_do_6_2_sack"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_do_6_2_sack, name:
"sctp_sf_do_6_2_sack"}, \
{
.fn = sctp_sf_do_6_2_sack, .name =
"sctp_sf_do_6_2_sack"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.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"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn:
sctp_sf_autoclose_timer_expire, \
name:
"sctp_sf_autoclose_timer_expire"}, \
{
.fn =
sctp_sf_autoclose_timer_expire, \
.name =
"sctp_sf_autoclose_timer_expire"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_timer_ignore, name:
"sctp_sf_timer_ignore"}, \
{
.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"}, \
{
.fn = sctp_sf_timer_ignore, .name =
"sctp_sf_timer_ignore"}, \
}
#define TYPE_SCTP_EVENT_TIMEOUT_PMTU_RAISE { \
/* SCTP_STATE_EMPTY */
\
{
fn: sctp_sf_bug, name:
"sctp_sf_bug"}, \
{
.fn = sctp_sf_bug, .name =
"sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name:
"sctp_sf_not_impl"}, \
{
.fn = sctp_sf_not_impl, .name =
"sctp_sf_not_impl"}, \
}
sctp_sm_table_entry_t
timeout_event_table
[
SCTP_NUM_TIMEOUT_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
...
...
@@ -1116,6 +1159,7 @@ sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM
TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
,
TYPE_SCTP_EVENT_TIMEOUT_T3_RTX
,
TYPE_SCTP_EVENT_TIMEOUT_T4_RTO
,
TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD
,
TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT
,
TYPE_SCTP_EVENT_TIMEOUT_SACK
,
TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE
,
...
...
@@ -1125,12 +1169,11 @@ sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM
sctp_sm_table_entry_t
*
sctp_chunk_event_lookup
(
sctp_cid_t
cid
,
sctp_state_t
state
)
{
if
(
state
>
SCTP_STATE_MAX
)
BUG
();
if
(
cid
<
0
)
return
&
nop
;
return
&
bug
;
if
(
cid
<=
SCTP_CID_BASE_MAX
)
if
(
cid
>=
0
&&
cid
<=
SCTP_CID_BASE_MAX
)
{
return
&
chunk_event_table
[
cid
][
state
];
}
switch
(
cid
)
{
case
SCTP_CID_ASCONF
:
...
...
@@ -1139,8 +1182,6 @@ sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t stat
case
SCTP_CID_ASCONF_ACK
:
return
&
chunk_event_table_asconf_ack
[
state
];
default:
return
&
nop
;
};
return
&
nop
;
return
&
chunk_event_table_unknown
[
state
];
}
}
net/sctp/socket.c
View file @
dd18325f
/* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 International Business Machines, Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001
-2002
International Business Machines, Corp.
* Copyright (c) 2001
-2002
Intel Corp.
* Copyright (c) 2001
-2002
Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
*
* This file is part of the SCTP kernel reference Implementation
...
...
@@ -82,8 +82,6 @@ static void sctp_wfree(struct sk_buff *skb);
static
int
sctp_wait_for_sndbuf
(
sctp_association_t
*
asoc
,
long
*
timeo_p
,
int
msg_len
);
static
int
sctp_wait_for_packet
(
struct
sock
*
sk
,
int
*
err
,
long
*
timeo_p
);
static
inline
void
sctp_sk_memcpy_msgname
(
struct
sock
*
sk
,
char
*
msgname
,
int
*
addr_len
,
struct
sk_buff
*
skb
);
static
inline
void
sctp_sk_addr_set
(
struct
sock
*
,
const
sockaddr_storage_t
*
newaddr
,
sockaddr_storage_t
*
saveaddr
);
...
...
@@ -326,8 +324,8 @@ static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs,
SCTP_DEBUG_PRINTK
(
"__sctp_bindx(sk: %p, addrs: %p, addrcnt: %d, "
"flags: %s)
\n
"
,
sk
,
addrs
,
addrcnt
,
(
BINDX_ADD_ADDR
==
flags
)
?
"ADD"
:
((
BINDX_REM_ADDR
==
flags
)
?
"REM"
:
"BOGUS"
));
(
BINDX_ADD_ADDR
==
flags
)
?
"ADD"
:
((
BINDX_REM_ADDR
==
flags
)
?
"REM"
:
"BOGUS"
));
switch
(
flags
)
{
case
BINDX_ADD_ADDR
:
...
...
@@ -500,9 +498,8 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
case
AF_INET
:
saveaddr
=
*
((
sockaddr_storage_t
*
)
&
addrs
[
cnt
]);
saveaddr
.
v4
.
sin_port
=
ntohs
(
saveaddr
.
v4
.
sin_port
);
/* verify the port */
saveaddr
.
v4
.
sin_port
=
ntohs
(
saveaddr
.
v4
.
sin_port
);
/* Verify the port. */
if
(
saveaddr
.
v4
.
sin_port
!=
bp
->
port
)
{
retval
=
-
EINVAL
;
goto
err_bindx_rem
;
...
...
@@ -606,7 +603,8 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
*
* Returns 0 if ok, <0 errno code on error.
*/
static
int
sctp_setsockopt_bindx
(
struct
sock
*
sk
,
struct
sockaddr_storage
*
addrs
,
static
int
sctp_setsockopt_bindx
(
struct
sock
*
sk
,
struct
sockaddr_storage
*
addrs
,
int
addrssize
,
int
op
)
{
struct
sockaddr_storage
*
kaddrs
;
...
...
@@ -614,8 +612,7 @@ static int sctp_setsockopt_bindx(struct sock* sk, struct sockaddr_storage *addrs
size_t
addrcnt
;
SCTP_DEBUG_PRINTK
(
"sctp_do_setsocktopt_bindx: sk %p addrs %p"
" addrssize %d opt %d
\n
"
,
sk
,
addrs
,
addrssize
,
op
);
" addrssize %d opt %d
\n
"
,
sk
,
addrs
,
addrssize
,
op
);
/* Do we have an integer number of structs sockaddr_storage? */
if
(
unlikely
(
addrssize
<=
0
||
...
...
@@ -851,7 +848,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
goto
out_unlock
;
}
if
(
sinfo_flags
&
MSG_ABORT
)
{
SCTP_DEBUG_PRINTK
(
"Aborting association: %p
\n
"
,
asoc
);
SCTP_DEBUG_PRINTK
(
"Aborting association: %p
\n
"
,
asoc
);
sctp_primitive_ABORT
(
asoc
,
NULL
);
err
=
0
;
goto
out_unlock
;
...
...
@@ -866,8 +863,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
* either the default or the user specified stream counts.
*/
if
(
sinfo
)
{
if
(
!
sinit
||
(
sinit
&&
!
sinit
->
sinit_num_ostreams
))
{
if
(
!
sinit
||
(
sinit
&&
!
sinit
->
sinit_num_ostreams
))
{
/* Check against the defaults. */
if
(
sinfo
->
sinfo_stream
>=
sp
->
initmsg
.
sinit_num_ostreams
)
{
...
...
@@ -1096,12 +1092,13 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
* flags - flags sent or received with the user message, see Section
* 5 for complete description of the flags.
*/
static
struct
sk_buff
*
sctp_skb_recv_datagram
(
struct
sock
*
,
int
,
int
,
int
*
);
static
struct
sk_buff
*
sctp_skb_recv_datagram
(
struct
sock
*
,
int
,
int
,
int
*
);
static
int
sctp_recvmsg
(
struct
sock
*
sk
,
struct
msghdr
*
msg
,
int
len
,
int
noblock
,
int
flags
,
int
*
addr_len
)
{
sctp_ulpevent_t
*
event
=
NULL
;
sctp_opt_t
*
sp
=
sctp_sk
(
sk
);
struct
sk_buff
*
skb
;
int
copied
;
int
err
=
0
;
...
...
@@ -1147,19 +1144,16 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
sock_recv_timestamp
(
msg
,
sk
,
skb
);
if
(
sctp_ulpevent_is_notification
(
event
))
{
msg
->
msg_flags
|=
MSG_NOTIFICATION
;
sp
->
pf
->
event_msgname
(
event
,
msg
->
msg_name
,
addr_len
);
}
else
{
/* Copy the address. */
if
(
addr_len
&&
msg
->
msg_name
)
sctp_sk_memcpy_msgname
(
sk
,
msg
->
msg_name
,
addr_len
,
skb
);
sp
->
pf
->
skb_msgname
(
skb
,
msg
->
msg_name
,
addr_len
);
}
/* Check if we allow SCTP_SNDRCVINFO. */
if
(
s
ctp_sk
(
sk
)
->
subscribe
.
sctp_data_io_event
)
if
(
s
p
->
subscribe
.
sctp_data_io_event
)
sctp_ulpevent_read_sndrcvinfo
(
event
,
msg
);
#if 0
/* FIXME: we should be calling IP
layer too
. */
/* FIXME: we should be calling IP
/IPv6 layers
. */
if (sk->protinfo.af_inet.cmsg_flags)
ip_cmsg_recv(msg, skb);
#endif
...
...
@@ -1176,7 +1170,8 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
return
err
;
}
static
inline
int
sctp_setsockopt_disable_fragments
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
static
inline
int
sctp_setsockopt_disable_fragments
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
{
int
val
;
...
...
@@ -1191,7 +1186,8 @@ static inline int sctp_setsockopt_disable_fragments(struct sock *sk, char *optva
return
0
;
}
static
inline
int
sctp_setsockopt_set_events
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
static
inline
int
sctp_setsockopt_set_events
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
{
if
(
optlen
!=
sizeof
(
struct
sctp_event_subscribe
))
return
-
EINVAL
;
...
...
@@ -1200,7 +1196,8 @@ static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval, int
return
0
;
}
static
inline
int
sctp_setsockopt_autoclose
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
static
inline
int
sctp_setsockopt_autoclose
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
{
sctp_opt_t
*
sp
=
sctp_sk
(
sk
);
...
...
@@ -1236,7 +1233,7 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
char
*
optval
,
int
optlen
)
{
int
retval
=
0
;
char
*
tmp
;
char
*
tmp
;
sctp_protocol_t
*
proto
=
sctp_get_protocol
();
struct
list_head
*
pos
;
sctp_func_t
*
af
;
...
...
@@ -1356,19 +1353,9 @@ static int sctp_init_sock(struct sock *sk)
proto
=
sctp_get_protocol
();
/* Create a per socket endpoint structure. Even if we
* change the data structure relationships, this may still
* be useful for storing pre-connect address information.
*/
ep
=
sctp_endpoint_new
(
proto
,
sk
,
GFP_KERNEL
);
if
(
!
ep
)
return
-
ENOMEM
;
sp
=
sctp_sk
(
sk
);
/* Initialize the SCTP per socket area. */
sp
->
ep
=
ep
;
sp
->
type
=
SCTP_SOCKET_UDP
;
/* FIXME: The next draft (04) of the SCTP Sockets Extensions
...
...
@@ -1425,6 +1412,16 @@ static int sctp_init_sock(struct sock *sk)
* for UDP-style sockets only.
*/
sp
->
autoclose
=
0
;
sp
->
pf
=
sctp_get_pf_specific
(
sk
->
family
);
/* Create a per socket endpoint structure. Even if we
* change the data structure relationships, this may still
* be useful for storing pre-connect address information.
*/
ep
=
sctp_endpoint_new
(
proto
,
sk
,
GFP_KERNEL
);
if
(
NULL
==
ep
)
return
-
ENOMEM
;
sp
->
ep
=
ep
;
SCTP_DBG_OBJCNT_INC
(
sock
);
return
0
;
...
...
@@ -1836,8 +1833,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
case
PF_INET6
:
SCTP_V6
(
tmpaddr
.
v6
.
sin6_family
=
AF_INET6
;
tmpaddr
.
v6
.
sin6_port
=
snum
;
tmpaddr
.
v6
.
sin6_addr
=
inet6_sk
(
sk
)
->
rcv_saddr
;
tmpaddr
.
v6
.
sin6_addr
=
inet6_sk
(
sk
)
->
rcv_saddr
;
)
break
;
...
...
@@ -1855,7 +1851,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
* that this port/socket (sk) combination are already
* in an endpoint.
*/
for
(
;
sk2
!=
NULL
;
sk2
=
sk2
->
bind_next
)
{
for
(
;
sk2
!=
NULL
;
sk2
=
sk2
->
bind_next
)
{
sctp_endpoint_t
*
ep2
;
ep2
=
sctp_sk
(
sk2
)
->
ep
;
...
...
@@ -1887,7 +1883,7 @@ static long sctp_get_port_local(struct sock *sk, unsigned short snum)
* SO_REUSEADDR on this socket -sk-).
*/
if
(
pp
->
sk
==
NULL
)
{
pp
->
fastreuse
=
sk
->
reuse
?
1
:
0
;
pp
->
fastreuse
=
sk
->
reuse
?
1
:
0
;
}
else
if
(
pp
->
fastreuse
&&
sk
->
reuse
==
0
)
{
pp
->
fastreuse
=
0
;
}
...
...
@@ -2073,7 +2069,7 @@ static sctp_bind_bucket_t *sctp_bucket_create(sctp_bind_hashbucket_t *head, unsi
pp
->
sk
=
NULL
;
if
((
pp
->
next
=
head
->
chain
)
!=
NULL
)
pp
->
next
->
pprev
=
&
pp
->
next
;
head
->
chain
=
pp
;
head
->
chain
=
pp
;
pp
->
pprev
=
&
head
->
chain
;
}
SCTP_DEBUG_PRINTK
(
"sctp_bucket_create() ends, pp=%p
\n
"
,
pp
);
...
...
@@ -2433,41 +2429,6 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, int no
return
NULL
;
}
/* Copy an approriately formatted address for msg_name. */
static
inline
void
sctp_sk_memcpy_msgname
(
struct
sock
*
sk
,
char
*
msgname
,
int
*
addr_len
,
struct
sk_buff
*
skb
)
{
struct
sockaddr_in
*
sin
;
struct
sockaddr_in6
*
sin6
__attribute__
((
unused
));
struct
sctphdr
*
sh
;
/* The sockets layer handles copying this out to user space. */
switch
(
sk
->
family
)
{
case
PF_INET
:
sin
=
(
struct
sockaddr_in
*
)
msgname
;
if
(
addr_len
)
*
addr_len
=
sizeof
(
struct
sockaddr_in
);
sin
->
sin_family
=
AF_INET
;
sh
=
(
struct
sctphdr
*
)
skb
->
h
.
raw
;
sin
->
sin_port
=
sh
->
source
;
sin
->
sin_addr
.
s_addr
=
skb
->
nh
.
iph
->
saddr
;
memset
(
sin
->
sin_zero
,
0
,
sizeof
(
sin
->
sin_zero
));
break
;
case
PF_INET6
:
SCTP_V6
(
/* FIXME: Need v6 code here. We should convert
* V4 addresses to PF_INET6 format. See ipv6/udp.c
* for an example. --jgrimm
*/
);
break
;
default:
/* Should not get here. */
break
;
};
}
static
inline
int
sctp_sendmsg_verify_name
(
struct
sock
*
sk
,
struct
msghdr
*
msg
)
{
sockaddr_storage_t
*
sa
;
...
...
net/sctp/transport.c
View file @
dd18325f
net/sctp/ulpevent.c
View file @
dd18325f
...
...
@@ -46,9 +46,10 @@
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
static
void
sctp_rcvmsg_rfree
(
struct
sk_buff
*
skb
);
static
void
sctp_ulpevent_set_owner_r
(
struct
sk_buff
*
skb
,
sctp_association_t
*
asoc
);
static
void
sctp_ulpevent_set_owner
(
struct
sk_buff
*
skb
,
const
sctp_association_t
*
asoc
);
/* Create a new sctp_ulpevent. */
sctp_ulpevent_t
*
sctp_ulpevent_new
(
int
size
,
int
msg_flags
,
int
priority
)
...
...
@@ -123,14 +124,12 @@ sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(const sctp_association_t *asoc,
struct
sctp_assoc_change
*
sac
;
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_assoc_change
),
MSG_NOTIFICATION
,
priority
);
MSG_NOTIFICATION
,
priority
);
if
(
!
event
)
goto
fail
;
sac
=
(
struct
sctp_assoc_change
*
)
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_assoc_change
));
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_assoc_change
));
/* Socket Extensions for SCTP
* 5.3.1.1 SCTP_ASSOC_CHANGE
...
...
@@ -199,6 +198,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(const sctp_association_t *asoc,
* All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored.
*/
sctp_ulpevent_set_owner
(
event
->
parent
,
asoc
);
sac
->
sac_assoc_id
=
sctp_assoc2id
(
asoc
);
return
event
;
...
...
@@ -227,14 +227,12 @@ sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change(
struct
sctp_paddr_change
*
spc
;
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_paddr_change
),
MSG_NOTIFICATION
,
priority
);
MSG_NOTIFICATION
,
priority
);
if
(
!
event
)
goto
fail
;
spc
=
(
struct
sctp_paddr_change
*
)
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_paddr_change
));
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_paddr_change
));
/* Sockets API Extensions for SCTP
* Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
...
...
@@ -287,12 +285,13 @@ sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change(
/* Socket Extensions for SCTP
* 5.3.1.1 SCTP_ASSOC_CHANGE
*
* s
a
c_assoc_id: sizeof (sctp_assoc_t)
* s
p
c_assoc_id: sizeof (sctp_assoc_t)
*
* The association id field, holds the identifier for the association.
* All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored.
*/
sctp_ulpevent_set_owner
(
event
->
parent
,
asoc
);
spc
->
spc_assoc_id
=
sctp_assoc2id
(
asoc
);
/* Sockets API Extensions for SCTP
...
...
@@ -360,9 +359,8 @@ sctp_ulpevent_t *sctp_ulpevent_make_remote_error(const sctp_association_t *asoc,
/* Embed the event fields inside the cloned skb. */
event
=
(
sctp_ulpevent_t
*
)
skb
->
cb
;
event
=
sctp_ulpevent_init
(
event
,
skb
,
MSG_NOTIFICATION
);
event
=
sctp_ulpevent_init
(
event
,
skb
,
MSG_NOTIFICATION
);
if
(
!
event
)
goto
fail
;
...
...
@@ -418,6 +416,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_remote_error(const sctp_association_t *asoc,
* All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored.
*/
sctp_ulpevent_set_owner
(
event
->
parent
,
asoc
);
sre
->
sre_assoc_id
=
sctp_assoc2id
(
asoc
);
return
event
;
...
...
@@ -515,9 +514,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
* The original send information associated with the undelivered
* message.
*/
memcpy
(
&
ssf
->
ssf_info
,
&
chunk
->
sinfo
,
sizeof
(
struct
sctp_sndrcvinfo
));
memcpy
(
&
ssf
->
ssf_info
,
&
chunk
->
sinfo
,
sizeof
(
struct
sctp_sndrcvinfo
));
/* Socket Extensions for SCTP
* 5.3.1.4 SCTP_SEND_FAILED
...
...
@@ -528,8 +525,8 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
* same association identifier. For TCP style socket, this field is
* ignored.
*/
sctp_ulpevent_set_owner
(
event
->
parent
,
asoc
);
ssf
->
ssf_assoc_id
=
sctp_assoc2id
(
asoc
);
return
event
;
fail:
...
...
@@ -541,7 +538,8 @@ sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
* Socket Extensions for SCTP - draft-01
* 5.3.1.5 SCTP_SHUTDOWN_EVENT
*/
sctp_ulpevent_t
*
sctp_ulpevent_make_shutdown_event
(
const
sctp_association_t
*
asoc
,
sctp_ulpevent_t
*
sctp_ulpevent_make_shutdown_event
(
const
sctp_association_t
*
asoc
,
__u16
flags
,
int
priority
)
{
...
...
@@ -549,14 +547,12 @@ sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *aso
struct
sctp_shutdown_event
*
sse
;
event
=
sctp_ulpevent_new
(
sizeof
(
struct
sctp_assoc_change
),
MSG_NOTIFICATION
,
priority
);
MSG_NOTIFICATION
,
priority
);
if
(
!
event
)
goto
fail
;
sse
=
(
struct
sctp_shutdown_event
*
)
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_shutdown_event
));
skb_put
(
event
->
parent
,
sizeof
(
struct
sctp_shutdown_event
));
/* Socket Extensions for SCTP
* 5.3.1.5 SCTP_SHUTDOWN_EVENT
...
...
@@ -591,6 +587,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *aso
* All notifications for a given association have the same association
* identifier. For TCP style socket, this field is ignored.
*/
sctp_ulpevent_set_owner
(
event
->
parent
,
asoc
);
sse
->
sse_assoc_id
=
sctp_assoc2id
(
asoc
);
return
event
;
...
...
@@ -607,8 +604,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(const sctp_association_t *aso
* 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
*/
sctp_ulpevent_t
*
sctp_ulpevent_make_rcvmsg
(
sctp_association_t
*
asoc
,
sctp_chunk_t
*
chunk
,
int
priority
)
sctp_chunk_t
*
chunk
,
int
priority
)
{
sctp_ulpevent_t
*
event
;
struct
sctp_sndrcvinfo
*
info
;
...
...
@@ -818,23 +814,33 @@ static void sctp_ulpevent_set_owner_r(struct sk_buff *skb, sctp_association_t *a
asoc
->
rwnd_over
=
skb
->
len
-
asoc
->
rwnd
;
asoc
->
rwnd
=
0
;
}
SCTP_DEBUG_PRINTK
(
"rwnd decreased by %d to (%u, %u)
\n
"
,
skb
->
len
,
asoc
->
rwnd
,
asoc
->
rwnd_over
);
}
/* A simple destructor to give up the reference to the association. */
static
void
sctp_ulpevent_rfree
(
struct
sk_buff
*
skb
)
{
sctp_ulpevent_t
*
event
;
event
=
(
sctp_ulpevent_t
*
)
skb
->
cb
;
sctp_association_put
(
event
->
asoc
);
}
/* Hold the association in case the msg_name needs read out of
* the association.
*/
static
void
sctp_ulpevent_set_owner
(
struct
sk_buff
*
skb
,
const
sctp_association_t
*
asoc
)
{
sctp_ulpevent_t
*
event
;
/* Cast away the const, as we are just wanting to
* bump the reference count.
*/
sctp_association_hold
((
sctp_association_t
*
)
asoc
);
skb
->
sk
=
asoc
->
base
.
sk
;
event
=
(
sctp_ulpevent_t
*
)
skb
->
cb
;
event
->
asoc
=
(
sctp_association_t
*
)
asoc
;
skb
->
destructor
=
sctp_ulpevent_rfree
;
}
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