Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
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