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
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
1686 additions
and
1169 deletions
+1686
-1169
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
net/sctp/ulpqueue.c
net/sctp/ulpqueue.c
+15
-15
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
...
...
@@ -66,7 +66,7 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc);
/* Allocate and initialize a new association */
sctp_association_t
*
sctp_association_new
(
const
sctp_endpoint_t
*
ep
,
const
struct
sock
*
sk
,
const
struct
sock
*
sk
,
sctp_scope_t
scope
,
int
priority
)
{
sctp_association_t
*
asoc
;
...
...
@@ -91,7 +91,7 @@ sctp_association_t *sctp_association_new(const sctp_endpoint_t *ep,
/* Intialize a new association from provided memory. */
sctp_association_t
*
sctp_association_init
(
sctp_association_t
*
asoc
,
const
sctp_endpoint_t
*
ep
,
const
sctp_endpoint_t
*
ep
,
const
struct
sock
*
sk
,
sctp_scope_t
scope
,
int
priority
)
...
...
@@ -109,19 +109,19 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
asoc
->
ep
=
(
sctp_endpoint_t
*
)
ep
;
sctp_endpoint_hold
(
asoc
->
ep
);
/* Hold the sock. */
/* Hold the sock.
*/
asoc
->
base
.
sk
=
(
struct
sock
*
)
sk
;
sock_hold
(
asoc
->
base
.
sk
);
/* Initialize the common base substructure. */
/* Initialize the common base substructure.
*/
asoc
->
base
.
type
=
SCTP_EP_TYPE_ASSOCIATION
;
/* Initialize the object handling fields. */
/* Initialize the object handling fields.
*/
atomic_set
(
&
asoc
->
base
.
refcnt
,
1
);
asoc
->
base
.
dead
=
0
;
asoc
->
base
.
malloced
=
0
;
/* Initialize the bind addr area. */
/* Initialize the bind addr area.
*/
sctp_bind_addr_init
(
&
asoc
->
base
.
bind_addr
,
ep
->
base
.
bind_addr
.
port
);
asoc
->
base
.
addr_lock
=
RW_LOCK_UNLOCKED
;
...
...
@@ -135,7 +135,7 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
asoc
->
pmtu
=
0
;
asoc
->
frag_point
=
0
;
/* Initialize the default association max_retrans and RTO values. */
/* Initialize the default association max_retrans and RTO values.
*/
asoc
->
max_retrans
=
ep
->
proto
->
max_retrans_association
;
asoc
->
rto_initial
=
ep
->
proto
->
rto_initial
;
asoc
->
rto_max
=
ep
->
proto
->
rto_max
;
...
...
@@ -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
)
{
...
...
@@ -383,12 +386,11 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
};
/* Set the port if it has not been set yet. */
if
(
0
==
asoc
->
peer
.
port
)
{
asoc
->
peer
.
port
=
*
port
;
}
if
(
0
==
asoc
->
peer
.
port
)
{
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
);
...
...
@@ -461,11 +463,21 @@ sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
sp
=
sctp_sk
(
asoc
->
base
.
sk
);
peer
->
hb_interval
=
sp
->
paddrparam
.
spp_hbinterval
*
HZ
;
/* Attach the remote transport to our 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
)
{
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
;
asoc
->
peer
.
active_path
=
peer
;
asoc
->
peer
.
retran_path
=
peer
;
...
...
@@ -617,7 +629,7 @@ __u32 __sctp_association_get_next_tsn(sctp_association_t *asoc)
asoc
->
next_tsn
++
;
asoc
->
unack_data
++
;
return
retval
;
return
retval
;
}
/* Allocate 'num' TSNs by incrementing the association's TSN by num. */
...
...
@@ -739,7 +751,7 @@ int sctp_cmp_addr_exact(const sockaddr_storage_t *ss1,
* Note: We are sly and return a shared, prealloced chunk.
*/
sctp_chunk_t
*
sctp_get_ecne_prepend
(
sctp_association_t
*
asoc
)
{
{
sctp_chunk_t
*
chunk
;
int
need_ecne
;
__u32
lowest_tsn
;
...
...
@@ -892,7 +904,7 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc)
/* Check to see if the association is freed in response to
* the incoming chunk. If so, get out of the while loop.
*/
*/
if
(
!
sctp_id2assoc
(
sk
,
associd
))
goto
out
;
...
...
@@ -967,7 +979,7 @@ void sctp_assoc_update(sctp_association_t *asoc, sctp_association_t *new)
* and peer's streams.
*/
for
(
i
=
0
;
i
<
SCTP_MAX_STREAM
;
i
++
)
{
asoc
->
ssn
[
i
]
=
0
;
asoc
->
ssn
[
i
]
=
0
;
asoc
->
ulpq
.
ssn
[
i
]
=
0
;
}
}
else
{
...
...
net/sctp/bind_addr.c
View file @
dd18325f
/* SCTP kernel reference Implementation
* Copyright (c) Cisco 1999,2000
* Copyright (c) Motorola 1999,2000,2001
* Copyright (c) Cisco 1999,2000
* Copyright (c) Motorola 1999,2000,2001
* Copyright (c) International Business Machines Corp., 2001
* Copyright (c) La Monte H.P. Yarroll 2001
*
* This file is part of the SCTP kernel reference implementation.
*
* A collection class to handle the storage of transport addresses.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* A collection class to handle the storage of transport addresses.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
...
...
@@ -83,7 +83,7 @@ int sctp_bind_addr_copy(sctp_bind_addr_t *dest, const sctp_bind_addr_t *src,
out:
if
(
error
)
sctp_bind_addr_clean
(
dest
);
return
error
;
}
...
...
@@ -356,7 +356,7 @@ int sctp_in_scope(const sockaddr_storage_t *addr, sctp_scope_t scope)
case
AF_INET
:
/* According to the SCTP IPv4 address scoping document -
* <draft-stewart-tsvwg-sctp-ipv4-00.txt>, the scope has
* a heirarchy of 5 levels:
* a heirarchy of 5 levels:
* Level 0 - unusable SCTP addresses
* Level 1 - loopback address
* Level 2 - link-local addresses
...
...
net/sctp/command.c
View file @
dd18325f
/* SCTP kernel reference Implementation Copyright (C) 1999-2001
* Cisco, Motorola, and IBM
* Copyright 2001 La Monte H.P. Yarroll
*
*
* This file is part of the SCTP kernel reference Implementation
*
*
* These functions manipulate sctp command sequences.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
...
...
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
...
...
@@ -5,46 +5,46 @@
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
*
*
* This file is part of the SCTP kernel reference Implementation
*
* This abstraction represents an SCTP endpoint.
*
* This abstraction represents an SCTP endpoint.
*
* This file is part of the implementation of the add-IP extension,
* based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001,
* for the SCTP kernel reference Implementation.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@austin.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
* Dajiang Zhang <dajiang.zhang@nokia.com>
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
...
...
@@ -92,15 +92,16 @@ 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. */
/* What type of endpoint are we? */
ep
->
base
.
type
=
SCTP_EP_TYPE_SOCKET
;
/* Initialize the basic object fields. */
/* Initialize the basic object fields. */
atomic_set
(
&
ep
->
base
.
refcnt
,
1
);
ep
->
base
.
dead
=
0
;
ep
->
base
.
dead
=
0
;
ep
->
base
.
malloced
=
1
;
/* Create an input queue. */
...
...
@@ -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,9 +260,10 @@ 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
,
const
sockaddr_storage_t
*
paddr
,
sctp_transport_t
**
transport
)
sctp_association_t
*
__sctp_endpoint_lookup_assoc
(
const
sctp_endpoint_t
*
endpoint
,
const
sockaddr_storage_t
*
paddr
,
sctp_transport_t
**
transport
)
{
int
rport
;
sctp_association_t
*
asoc
;
...
...
@@ -310,7 +320,7 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep)
asoc
=
NULL
;
inqueue
=
&
ep
->
base
.
inqueue
;
sk
=
ep
->
base
.
sk
;
sk
=
ep
->
base
.
sk
;
while
(
NULL
!=
(
chunk
=
sctp_pop_inqueue
(
inqueue
)))
{
subtype
.
chunk
=
chunk
->
chunk_hdr
->
type
;
...
...
@@ -343,15 +353,15 @@ static void sctp_endpoint_bh_rcv(sctp_endpoint_t *ep)
/* FIX ME We really would rather NOT have to use
* GFP_ATOMIC.
*/
error
=
sctp_do_sm
(
SCTP_EVENT_T_CHUNK
,
subtype
,
state
,
error
=
sctp_do_sm
(
SCTP_EVENT_T_CHUNK
,
subtype
,
state
,
ep
,
asoc
,
chunk
,
GFP_ATOMIC
);
if
(
error
!=
0
)
goto
err_out
;
/* Check to see if the endpoint is freed in response to
/* Check to see if the endpoint is freed in response to
* the incoming chunk. If so, get out of the while loop.
*/
*/
if
(
!
sctp_sk
(
sk
)
->
ep
)
goto
out
;
}
...
...
@@ -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
...
...
@@ -5,43 +5,43 @@
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
*
*
* This file is part of the SCTP kernel reference Implementation
*
* These functions handle all input from the IP layer into SCTP.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* These functions handle all input from the IP layer into SCTP.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Xingang Guo <xingang.guo@intel.com>
* Jon Grimm <jgrimm@us.ibm.com>
* Hui Huang <hui.huang@nokia.com>
* Daisy Chang <daisyc@us.ibm.com>
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
...
...
@@ -57,7 +57,7 @@
#include <net/sctp/sm.h>
/* Forward declarations for internal helpers. */
static
int
sctp_rcv_ootb
(
struct
sk_buff
*
);
static
int
sctp_rcv_ootb
(
struct
sk_buff
*
);
sctp_association_t
*
__sctp_rcv_lookup
(
struct
sk_buff
*
skb
,
const
sockaddr_storage_t
*
laddr
,
const
sockaddr_storage_t
*
paddr
,
...
...
@@ -639,7 +639,7 @@ static sctp_association_t *__sctp_rcv_initack_lookup(struct sk_buff *skb,
/* Lookup an association for an inbound skb. */
sctp_association_t
*
__sctp_rcv_lookup
(
struct
sk_buff
*
skb
,
const
sockaddr_storage_t
*
paddr
,
const
sockaddr_storage_t
*
laddr
,
const
sockaddr_storage_t
*
laddr
,
sctp_transport_t
**
transportp
)
{
sctp_association_t
*
asoc
;
...
...
net/sctp/ipv6.c
View file @
dd18325f
...
...
@@ -2,36 +2,36 @@
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
* Copyright (c) 2002 International Business Machines, Corp.
*
*
* This file is part of the SCTP kernel reference Implementation
*
*
* SCTP over IPv6.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* Le Yanqun <yanqun.le@nokia.com>
* Hui Huang <hui.huang@nokia.com>
* La Monte H.P. Yarroll <piggy@acm.org>
...
...
@@ -40,7 +40,7 @@
*
* Based on:
* linux/net/ipv6/tcp_ipv6.c
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
...
...
@@ -145,7 +145,7 @@ static inline int sctp_v6_xmit(struct sk_buff *skb)
IPV6_ADDR_LOOPBACK
))
{
ipv6_addr_copy
(
&
saddr
,
&
np
->
daddr
);
}
}
}
fl
.
fl6_src
=
&
saddr
;
}
else
{
fl
.
fl6_src
=
&
np
->
saddr
;
...
...
@@ -177,7 +177,7 @@ int sctp_v6_get_dst_mtu(const sockaddr_storage_t *address)
if
(
dst
)
{
dst_mtu
=
dst
->
pmtu
;
SCTP_DEBUG_PRINTK
(
"sctp_v6_get_dst_mtu: "
"ip6_route_output: dev:%s pmtu:%d
\n
"
,
"ip6_route_output: dev:%s pmtu:%d
\n
"
,
dst
->
dev
->
name
,
dst_mtu
);
dst_release
(
dst
);
}
else
{
...
...
@@ -189,11 +189,85 @@ 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
,
.
bind
=
inet6_bind
,
.
connect
=
inet_dgram_connect
,
.
connect
=
inet_dgram_connect
,
.
socketpair
=
sock_no_socketpair
,
.
accept
=
inet_accept
,
.
getname
=
inet6_getname
,
...
...
@@ -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
...
...
@@ -2,41 +2,41 @@
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 International Business Machines, Corp.
*
*
* This file is part of the SCTP kernel reference Implementation
*
*
* These functions handle output processing.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@austin.ibm.com>
* Sridhar Samudrala <sri@us.ibm.com>
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
...
...
@@ -48,7 +48,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/init.h>
#include <net/inet_ecn.h>
#include <net/inet_ecn.h>
#include <net/icmp.h>
#ifndef TEST_FRAME
...
...
@@ -113,7 +113,7 @@ void sctp_packet_free(sctp_packet_t *packet)
{
sctp_chunk_t
*
chunk
;
while
(
NULL
!=
while
(
NULL
!=
(
chunk
=
(
sctp_chunk_t
*
)
skb_dequeue
(
&
packet
->
chunks
)))
{
sctp_free_chunk
(
chunk
);
}
...
...
@@ -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
;
}
...
...
@@ -305,7 +304,7 @@ int sctp_packet_transmit(sctp_packet_t *packet)
*/
if
((
1
==
chunk
->
num_times_sent
)
&&
(
!
transport
->
rto_pending
))
{
chunk
->
rtt_in_progress
=
1
;
chunk
->
rtt_in_progress
=
1
;
transport
->
rto_pending
=
1
;
}
packet_has_data
=
1
;
...
...
@@ -337,9 +336,9 @@ int sctp_packet_transmit(sctp_packet_t *packet)
}
/* Build the SCTP header. */
sh
=
(
struct
sctphdr
*
)
skb_push
(
nskb
,
sizeof
(
struct
sctphdr
));
sh
->
source
=
htons
(
packet
->
source_port
);
sh
->
dest
=
htons
(
packet
->
destination_port
);
sh
=
(
struct
sctphdr
*
)
skb_push
(
nskb
,
sizeof
(
struct
sctphdr
));
sh
->
source
=
htons
(
packet
->
source_port
);
sh
->
dest
=
htons
(
packet
->
destination_port
);
/* From 6.8 Adler-32 Checksum Calculation:
* After the packet is constructed (containing the SCTP common
...
...
@@ -349,8 +348,8 @@ int sctp_packet_transmit(sctp_packet_t *packet)
* 1) Fill in the proper Verification Tag in the SCTP common
* header and initialize the checksum field to 0's.
*/
sh
->
vtag
=
htonl
(
packet
->
vtag
);
sh
->
checksum
=
0
;
sh
->
vtag
=
htonl
(
packet
->
vtag
);
sh
->
checksum
=
0
;
/* 2) Calculate the Adler-32 checksum of the whole packet,
* including the SCTP common header and all the
...
...
@@ -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
)
{
...
...
@@ -516,11 +517,11 @@ static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, sctp_chunk_t *
"transport: %p, cwnd: %d, "
"ssthresh: %d, flight_size: %d, "
"pba: %d
\n
"
,
__FUNCTION__
,
transport
,
transport
->
cwnd
,
transport
->
ssthresh
,
transport
->
flight_size
,
transport
->
partial_bytes_acked
);
__FUNCTION__
,
transport
,
transport
->
cwnd
,
transport
->
ssthresh
,
transport
->
flight_size
,
transport
->
partial_bytes_acked
);
}
/* RFC 2960 6.1 Transmission of DATA Chunks
...
...
@@ -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
,
__u8
fast_retransmit
)
/* 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
))
{
...
...
@@ -224,7 +215,7 @@ void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport,
* should be added to the retransmit queue. If we are doing
* retransmission due to a timeout, only the chunks that are
* not yet acked should be added to the retransmit queue.
*/
*/
if
((
fast_retransmit
&&
!
chunk
->
fast_retransmit
)
||
(
!
fast_retransmit
&&
chunk
->
tsn_gap_acked
))
{
list_add_tail
(
lchunk
,
&
tlist
);
...
...
@@ -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
;
}
...
...
@@ -327,7 +337,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
/* If a chunk has been tried for more than SCTP_DEF_MAX_SEND
* times, discard it, and check the empty flag of the outqueue.
*
*
--xguo
*
--xguo
*/
if (chunk->snd_count > SCTP_DEF_MAX_SEND) {
sctp_free_chunk(chunk);
...
...
@@ -339,7 +349,7 @@ static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
switch
(
status
)
{
case
SCTP_XMIT_PMTU_FULL
:
/* Send this packet. */
/* Send this packet.
*/
if
((
error
=
(
*
q
->
force_output
)(
pkt
))
==
0
)
*
start_timer
=
1
;
...
...
@@ -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
;
...
...
@@ -407,7 +415,7 @@ void sctp_xmit_frag(sctp_outqueue_t *q, struct sk_buff *pos,
if
(
!
skb_queue_empty
(
queue
))
{
SCTP_DEBUG_PRINTK
(
"sctp_xmit_frag: q not empty. "
"adding 0x%x to outqueue
\n
"
,
ntohl
(
frag
->
subh
.
data_hdr
->
tsn
));
ntohl
(
frag
->
subh
.
data_hdr
->
tsn
));
if
(
pos
)
{
skb_insert
(
pos
,
(
struct
sk_buff
*
)
frag
);
}
else
{
...
...
@@ -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
;
...
...
@@ -519,7 +528,7 @@ sctp_chunk_t *sctp_fragment_chunk(sctp_chunk_t *chunk, size_t max_frag_data_len)
/* Make the first fragment. */
first_frag
=
sctp_make_datafrag
(
asoc
,
sinfo
,
max_frag_data_len
,
data_ptr
,
SCTP_DATA_FIRST_FRAG
,
ssn
);
data_ptr
,
SCTP_DATA_FIRST_FRAG
,
ssn
);
if
(
!
first_frag
)
goto
err
;
...
...
@@ -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
;
...
...
@@ -641,7 +653,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
* chunk->transport, even it's inactive.
*/
if
(
chunk
->
chunk_hdr
->
type
!=
SCTP_CID_HEARTBEAT
)
new_transport
=
asoc
->
peer
.
active_path
;
new_transport
=
asoc
->
peer
.
active_path
;
}
/* Are we switching transports?
...
...
@@ -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
:
...
...
@@ -698,17 +710,17 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
default:
/* We built a chunk with an illegal type! */
BUG
();
BUG
();
};
}
/* 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. */
...
...
@@ -809,12 +827,11 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
:
"Illegal Chunk"
);
SCTP_DEBUG_PRINTK
(
"TX TSN 0x%x skb->head "
"%p skb->users %d.
\n
"
,
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
chunk
->
skb
?
chunk
->
skb
->
head
:
0
,
chunk
->
skb
?
atomic_read
(
&
chunk
->
skb
->
users
)
:
-
1
);
"%p skb->users %d.
\n
"
,
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
chunk
->
skb
?
chunk
->
skb
->
head
:
0
,
chunk
->
skb
?
atomic_read
(
&
chunk
->
skb
->
users
)
:
-
1
);
/* Add the chunk to the packet. */
status
=
(
*
q
->
build_output
)(
packet
,
chunk
);
...
...
@@ -826,8 +843,9 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
* the chunk back on the output queue.
*/
SCTP_DEBUG_PRINTK
(
"sctp_flush_outqueue: could"
"not transmit TSN: 0x%x, status: %d
\n
"
,
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
status
);
"not transmit TSN: 0x%x, status: %d
\n
"
,
ntohl
(
chunk
->
subh
.
data_hdr
->
tsn
),
status
);
skb_queue_head
(
queue
,
(
struct
sk_buff
*
)
chunk
);
goto
sctp_flush_out
;
break
;
...
...
@@ -836,7 +854,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
sctp_chunk_t
*
frag
;
frag
=
sctp_fragment_chunk
(
chunk
,
packet
->
transport
->
asoc
->
frag_point
);
packet
->
transport
->
asoc
->
frag_point
);
if
(
!
frag
)
{
/* We could not fragment due to out of
* memory condition. Free the original
...
...
@@ -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
;
}
;
break
;
}
sctp_flush_out:
/* Before returning, examine all the transports touched in
...
...
@@ -901,7 +925,7 @@ int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
if
(
packet
->
size
!=
SCTP_IP_OVERHEAD
)
error
=
(
*
q
->
force_output
)(
packet
);
}
return
error
;
}
...
...
@@ -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,10 +1331,11 @@ 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
,
transport
,
SCTP_TRANSPORT_UP
,
SCTP_RECEIVED_SACK
);
sctp_assoc_control_transport
(
transport
->
asoc
,
transport
,
SCTP_TRANSPORT_UP
,
SCTP_RECEIVED_SACK
);
}
sctp_transport_raise_cwnd
(
transport
,
sack_ctsn
,
...
...
@@ -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
/* SCTP kernel reference Implementation
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
*
*
* This file is part of the SCTP kernel reference Implementation
*
*
* These functions implement the SCTP primitive functions from Section 10.
*
*
* Note that the descriptions from the specification are USER level
* functions--this file is the functions which populate the struct proto
* for SCTP which is the BOTTOM of the sockets interface.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Narasimha Budihal <narasimha@refcode.org>
* Karl Knutson <karl@athena.chicago.il.us>
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
...
...
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. */
...
...
@@ -227,8 +231,8 @@ int sctp_copy_local_addr_list(sctp_protocol_t *proto, sctp_bind_addr_t *bp,
long
flags
__attribute__
((
unused
));
sctp_spin_lock_irqsave
(
&
proto
->
local_addr_lock
,
flags
);
list_for_each
(
pos
,
&
proto
->
local_addr_list
)
{
addr
=
list_entry
(
pos
,
struct
sockaddr_storage_list
,
list
);
list_for_each
(
pos
,
&
proto
->
local_addr_list
)
{
addr
=
list_entry
(
pos
,
struct
sockaddr_storage_list
,
list
);
if
(
sctp_in_scope
(
&
addr
->
a
,
scope
))
{
/* Now that the address is in scope, check to see if
* the address type is really supported by the local
...
...
@@ -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
));
...
...
@@ -312,8 +316,8 @@ int sctp_ctl_sock_init(void)
err
=
sock_create
(
family
,
SOCK_SEQPACKET
,
IPPROTO_SCTP
,
&
sctp_ctl_socket
);
if
(
err
<
0
)
{
printk
(
KERN_ERR
"SCTP: Failed to create the SCTP control socket.
\n
"
);
printk
(
KERN_ERR
"SCTP: Failed to create the SCTP control socket.
\n
"
);
return
err
;
}
sctp_ctl_socket
->
sk
->
allocation
=
GFP_ATOMIC
;
...
...
@@ -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,9 +499,11 @@ 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
*/
* 14. Suggested SCTP Protocol Parameter Values
*/
/* The following protocol parameters are RECOMMENDED: */
/* RTO.Initial - 3 seconds */
sctp_proto
.
rto_initial
=
SCTP_RTO_INITIAL
;
...
...
@@ -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
...
...
@@ -9,36 +9,36 @@
* This file includes part of the implementation of the add-IP extension,
* based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001,
* for the SCTP kernel reference Implementation.
*
*
* These functions work with the state functions in sctp_sm_statefuns.c
* to implement the state operations. These functions implement the
* steps which require modifying existing data structures.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
* C. Robin <chris@hundredacre.ac.uk>
...
...
@@ -73,7 +73,7 @@
* support any address type.
*/
static
const
sctp_supported_addrs_param_t
sat_param
=
{
{
{
SCTP_PARAM_SUPPORTED_ADDRESS_TYPES
,
__constant_htons
(
SCTP_SAT_LEN
),
},
...
...
@@ -204,7 +204,7 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc,
* PLEASE DO NOT FIXME [This version does not support Host Name.]
*/
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_INIT
,
0
,
chunksize
);
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_INIT
,
0
,
chunksize
);
if
(
!
retval
)
goto
nodata
;
...
...
@@ -1204,7 +1204,7 @@ sctp_association_t *sctp_make_temp_asoc(const sctp_endpoint_t *ep,
case
6
:
asoc
->
c
.
peer_addr
.
v6
.
sin6_family
=
AF_INET6
;
asoc
->
c
.
peer_addr
.
v6
.
sin6_port
asoc
->
c
.
peer_addr
.
v6
.
sin6_port
=
ntohs
(
chunk
->
sctp_hdr
->
source
);
asoc
->
c
.
peer_addr
.
v6
.
sin6_flowinfo
=
0
;
/* BUG BUG BUG */
asoc
->
c
.
peer_addr
.
v6
.
sin6_addr
=
chunk
->
skb
->
nh
.
ipv6h
->
saddr
;
...
...
@@ -1245,7 +1245,7 @@ sctp_cookie_param_t *sctp_pack_cookie(const sctp_endpoint_t *ep,
* functions simpler to write.
*/
if
(
bodysize
%
SCTP_COOKIE_MULTIPLE
)
bodysize
+=
SCTP_COOKIE_MULTIPLE
bodysize
+=
SCTP_COOKIE_MULTIPLE
-
(
bodysize
%
SCTP_COOKIE_MULTIPLE
);
*
cookie_len
=
headersize
+
bodysize
;
...
...
@@ -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.
...
...
@@ -1437,7 +1438,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
for
(
param
.
v
=
peer_init
->
init_hdr
.
params
;
param
.
v
<
end
;
param
.
v
+=
WORD_ROUND
(
ntohs
(
param
.
p
->
length
)))
{
if
(
!
sctp_process_param
(
asoc
,
param
,
peer_addr
,
cid
,
if
(
!
sctp_process_param
(
asoc
,
param
,
peer_addr
,
cid
,
priority
))
goto
clean_up
;
}
...
...
@@ -1461,7 +1462,7 @@ void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
*/
if
(
asoc
->
c
.
sinit_num_ostreams
>
ntohs
(
peer_init
->
init_hdr
.
num_inbound_streams
))
{
asoc
->
c
.
sinit_num_ostreams
=
asoc
->
c
.
sinit_num_ostreams
=
ntohs
(
peer_init
->
init_hdr
.
num_inbound_streams
);
}
...
...
@@ -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
/* SCTP kernel reference Implementation
/* SCTP kernel reference Implementation
* Copyright (c) 1999 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2002 International Business Machines Corp.
*
*
* This file is part of the SCTP kernel reference Implementation
*
*
* These functions work with the state functions in sctp_sm_statefuns.c
* to implement that state operations. These functions implement the
* steps which require modifying existing data structures.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@austin.ibm.com>
...
...
@@ -119,7 +119,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
int
priority
)
{
sctp_cmd_seq_t
commands
;
sctp_sm_table_entry_t
*
state_fn
;
sctp_sm_table_entry_t
*
state_fn
;
sctp_disposition_t
status
;
int
error
=
0
;
typedef
const
char
*
(
printfn_t
)(
sctp_subtype_t
);
...
...
@@ -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
));
...
...
@@ -602,7 +612,7 @@ static sctp_chunk_t *sctp_do_ecn_ecne_work(sctp_association_t *asoc,
{
sctp_chunk_t
*
repl
;
sctp_transport_t
*
transport
;
/* Our previously transmitted packet ran into some congestion
* so we should take action by reducing cwnd and ssthresh
* and then ACK our peer that we we've done so by
...
...
@@ -716,7 +726,7 @@ int sctp_gen_sack(sctp_association_t *asoc, int force, sctp_cmd_seq_t *commands)
error
=
sctp_push_outqueue
(
&
asoc
->
outqueue
,
sack
);
/* Stop the SACK timer. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_SACK
));
}
...
...
@@ -785,7 +795,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
if
(
!
mod_timer
(
&
transport
->
T3_rtx_timer
,
jiffies
+
(
HZ
/
20
)))
sctp_transport_hold
(
transport
);
goto
out_unlock
;
}
}
/* Is this transport really dead and just waiting around for
* the timer to let go of the reference?
...
...
@@ -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
;
...
...
@@ -890,7 +908,7 @@ void sctp_generate_heartbeat_event(unsigned long data)
if
(
!
mod_timer
(
&
transport
->
hb_timer
,
jiffies
+
(
HZ
/
20
)))
sctp_transport_hold
(
transport
);
goto
out_unlock
;
}
}
/* Is this structure just waiting around for us to actually
* get destroyed?
...
...
@@ -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
...
...
@@ -5,36 +5,36 @@
* Copyright (c) 2002 Nokia Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
*
* This is part of the SCTP Linux Kernel Reference Implementation.
*
* These are the state functions for the state machine.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Mathew Kotowsky <kotowsky@sctp.org>
...
...
@@ -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.
...
...
@@ -263,7 +237,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
/*
* Note:
After sending out INIT ACK with the State Cookie parameter,
* Note:
After sending out INIT ACK with the State Cookie parameter,
* "Z" MUST NOT allocate any resources, nor keep any states for the
* new association. Otherwise, "Z" will be vulnerable to resource
* attacks.
...
...
@@ -324,7 +298,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep,
return
SCTP_DISPOSITION_VIOLATION
;
/* Grab the INIT header. */
chunk
->
subh
.
init_hdr
=
(
sctp_inithdr_t
*
)
chunk
->
skb
->
data
;
chunk
->
subh
.
init_hdr
=
(
sctp_inithdr_t
*
)
chunk
->
skb
->
data
;
init_tag
=
ntohl
(
chunk
->
subh
.
init_hdr
->
init_tag
);
...
...
@@ -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
;
...
...
@@ -428,7 +399,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const sctp_endpoint_t *ep,
* control endpoint, responding with an ABORT.
*/
if
(
ep
==
sctp_sk
((
sctp_get_ctl_sock
()))
->
ep
)
return
sctp_sf_ootb
(
ep
,
asoc
,
type
,
arg
,
commands
);
return
sctp_sf_ootb
(
ep
,
asoc
,
type
,
arg
,
commands
);
/* "Decode" the chunk. We have no optional parameters so we
* are in good shape.
...
...
@@ -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
);
};
}
...
...
@@ -560,7 +530,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const sctp_endpoint_t *ep,
SCTP_STATE
(
SCTP_STATE_ESTABLISHED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_HB_TIMERS_START
,
SCTP_NULL
());
if
(
asoc
->
autoclose
)
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_START
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_START
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_AUTOCLOSE
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TRANSMIT
,
SCTP_NULL
());
...
...
@@ -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.
...
...
@@ -751,7 +720,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const sctp_endpoint_t *ep,
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
hbinfo
=
(
sctp_sender_hb_info_t
*
)
chunk
->
skb
->
data
;
from_addr
=
hbinfo
->
daddr
;
from_addr
=
hbinfo
->
daddr
;
link
=
sctp_assoc_lookup_paddr
(
asoc
,
&
from_addr
);
/* This should never happen, but lets log it if so. */
...
...
@@ -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
;
}
...
...
@@ -810,7 +778,7 @@ static void sctp_tietags_populate(sctp_association_t *new_asoc,
break
;
/* 5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
*
COOKIE-WAIT and SHUTDOWN-ACK-SENT
* COOKIE-WAIT and SHUTDOWN-ACK-SENT
*/
default:
new_asoc
->
c
.
my_ttag
=
asoc
->
c
.
my_vtag
;
...
...
@@ -843,10 +811,10 @@ static char sctp_tietags_compare(sctp_association_t *new_asoc,
/* In this case, the peer may have restarted. */
if
((
asoc
->
c
.
my_vtag
!=
new_asoc
->
c
.
my_vtag
)
&&
(
asoc
->
c
.
peer_vtag
!=
new_asoc
->
c
.
peer_vtag
)
&&
(
asoc
->
c
.
my_vtag
==
new_asoc
->
c
.
my_ttag
)
&&
(
asoc
->
c
.
my_vtag
==
new_asoc
->
c
.
my_ttag
)
&&
(
asoc
->
c
.
peer_vtag
==
new_asoc
->
c
.
peer_ttag
))
return
'A'
;
/* Collision case D.
* Note: Test case D first, otherwise it may be incorrectly
* identified as second case of B if the value of the Tie_tag is
...
...
@@ -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. */
...
...
@@ -927,7 +895,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(const sctp_endpoint_t *ep,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
repl
));
/*
* Note: After sending out INIT ACK with the State Cookie parameter,
* Note: After sending out INIT ACK with the State Cookie parameter,
* "Z" MUST NOT allocate any resources for this new association.
* Otherwise, "Z" will be vulnerable to resource attacks.
*/
...
...
@@ -1072,7 +1040,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const sctp_endpoint_t *ep,
list_for_each
(
pos
,
&
new_asoc
->
peer
.
transport_addr_list
)
{
new_addr
=
list_entry
(
pos
,
sctp_transport_t
,
transports
);
found
=
1
;
list_for_each_safe
(
pos2
,
temp
,
list_for_each_safe
(
pos2
,
temp
,
&
asoc
->
peer
.
transport_addr_list
)
{
addr
=
list_entry
(
pos2
,
sctp_transport_t
,
transports
);
if
(
!
sctp_cmp_addr_exact
(
&
new_addr
->
ipaddr
,
...
...
@@ -1256,7 +1224,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const sctp_endpoint_t *ep,
if
(
SCTP_STATE_ESTABLISHED
!=
asoc
->
state
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_ESTABLISHED
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_HB_TIMERS_START
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_HB_TIMERS_START
,
SCTP_NULL
());
/* RFC 2960 5.1 Normal Establishment of an Association
...
...
@@ -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
...
...
@@ -1335,25 +1302,24 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const sctp_endpoint_t *ep,
*/
new_asoc
=
sctp_unpack_cookie
(
ep
,
asoc
,
chunk
,
GFP_ATOMIC
,
&
error
);
/* FIXME:
/* FIXME:
* If the re-build failed, what is the proper error path
* from here?
*
* [We should abort the association. --piggy]
*/
if
(
!
new_asoc
)
{
/* FIXME: Several errors are possible. A bad cookie should
* be silently discarded, but think about logging it too.
*/
switch
(
error
)
{
case
-
SCTP_IERROR_NOMEM
:
goto
nomem
;
case
-
SCTP_IERROR_BAD_SIG
:
default:
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
};
/* FIXME: Several errors are possible. A bad cookie should
* be silently discarded, but think about logging it too.
*/
switch
(
error
)
{
case
-
SCTP_IERROR_NOMEM
:
goto
nomem
;
case
-
SCTP_IERROR_BAD_SIG
:
default:
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
};
}
/* Compare the tie_tag in cookie with the verification tag of
...
...
@@ -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
...
...
@@ -1442,7 +1467,7 @@ sctp_disposition_t do_5_2_6_stale(const sctp_endpoint_t *ep,
__u8 *addrs;
int addrs_len;
time_t rtt;
struct sctpCookiePreserve bht;
struct sctpCookiePreserve bht;
/* If we have gotten too many failures, give up. */
if (1 + asoc->counters[SctpCounterInits] > asoc->max_init_attempts) {
...
...
@@ -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
;
}
/*
...
...
@@ -1585,70 +1611,9 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const sctp_endpoint_t *ep,
{
/* There is a single T1 timer, so we should be able to use
* common function with the COOKIE-WAIT state.
*/
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;
return
sctp_sf_cookie_wait_abort
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
#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,9 +1683,8 @@ 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
,
arg
,
commands
);
disposition
=
sctp_sf_do_9_2_shutdown_ack
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/* - verify, by checking the Cumulative TSN Ack field of the
...
...
@@ -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
*
...
...
@@ -1780,7 +1780,7 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const sctp_endpoint_t *ep,
cwr
->
lowest_tsn
=
ntohl
(
cwr
->
lowest_tsn
);
/* Does this CWR ack the last sent congestion notification? */
/* Does this CWR ack the last sent congestion notification? */
if
(
TSN_lte
(
asoc
->
last_ecne_tsn
,
cwr
->
lowest_tsn
))
{
/* Stop sending ECNE. */
sctp_add_cmd_sf
(
commands
,
...
...
@@ -1844,7 +1844,7 @@ sctp_disposition_t sctp_sf_do_ecne(const sctp_endpoint_t *ep,
if
(
TSN_lt
(
asoc
->
last_cwr_tsn
,
ecne
->
lowest_tsn
))
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ECN_ECNE
,
SCTP_U32
(
ecne
->
lowest_tsn
));
}
}
return
SCTP_DISPOSITION_CONSUME
;
}
...
...
@@ -1979,13 +1979,11 @@ 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
;
}
/* We are accepting this DATA chunk. */
/* We are accepting this DATA chunk.
*/
/* Record the fact that we have received this TSN. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPORT_TSN
,
SCTP_U32
(
tsn
));
...
...
@@ -2029,7 +2027,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const sctp_endpoint_t *ep,
*
* The SCTP endpoint MUST always acknowledge the reception of
* each valid DATA chunk.
*
*
* The guidelines on delayed acknowledgement algorithm
* specified in Section 4.2 of [RFC2581] SHOULD be followed.
* Specifically, an acknowledgement SHOULD be generated for at
...
...
@@ -2142,7 +2140,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const sctp_endpoint_t *ep,
*/
if
(
!
chunk
->
ecn_ce_done
)
{
chunk
->
ecn_ce_done
=
1
;
if
(
INET_ECN_is_ce
(
chunk
->
skb
->
nh
.
iph
->
tos
)
&&
if
(
INET_ECN_is_ce
(
chunk
->
skb
->
nh
.
iph
->
tos
)
&&
asoc
->
peer
.
ecn_capable
)
{
/* Do real work as sideffect. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ECN_CE
,
...
...
@@ -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
)
...
...
@@ -2524,7 +2522,7 @@ sctp_disposition_t sctp_sf_ootb(const sctp_endpoint_t *ep,
if
(
ootb_shut_ack
)
sctp_sf_shut_8_4_5
(
ep
,
asoc
,
type
,
arg
,
commands
);
else
sctp_sf_tabort_8_4_8
(
ep
,
asoc
,
type
,
arg
,
commands
);
sctp_sf_tabort_8_4_8
(
ep
,
asoc
,
type
,
arg
,
commands
);
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
...
...
@@ -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
/*
...
...
@@ -2821,7 +2961,7 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const sctp_endpoint_t *ep,
* or else move the association allocation/init into this function.
* The association structure is brand new before calling this
* function, so would not be a sideeffect if the allocation
* moved into this function. --jgrimm
* moved into this function. --jgrimm
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SET_BIND_ADDR
,
(
sctp_arg_t
)
bp
);
...
...
@@ -2974,13 +3114,19 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(const sctp_endpoint_t *ep,
* if necessary to fill gaps.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_STATE
,
SCTP_STATE
(
SCTP_STATE_SHUTDOWN_PENDING
));
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
,
arg
,
commands
);
disposition
=
sctp_sf_do_9_2_start_shutdown
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
return
disposition
;
}
...
...
@@ -3034,7 +3180,7 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(const sctp_endpoint_t *ep,
/* Generate ABORT chunk to send the peer. */
abort
=
sctp_make_abort
(
asoc
,
NULL
,
0
);
if
(
!
abort
)
retval
=
SCTP_DISPOSITION_NOMEM
;
retval
=
SCTP_DISPOSITION_NOMEM
;
else
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
abort
));
...
...
@@ -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
());
/* Delete the established association. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_NULL
());
return
retval
;
}
...
...
@@ -3090,11 +3232,12 @@ 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
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
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
,
sctp_cmd_seq_t
*
commands
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T1_INIT
));
...
...
@@ -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:
...
...
@@ -3148,19 +3291,41 @@ sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown(
* (timers)
*/
sctp_disposition_t
sctp_sf_cookie_wait_prm_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
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:
...
...
@@ -3174,10 +3339,10 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(const sctp_endpoint_t *ep,
* (timers)
*/
sctp_disposition_t
sctp_sf_cookie_echoed_prm_abort
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
/* There is a single T1 timer, so we should be able to use
* common function with the COOKIE-WAIT state.
...
...
@@ -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
*
...
...
@@ -3218,10 +3464,10 @@ sctp_disposition_t sctp_sf_ignore_primitive(const sctp_endpoint_t *ep,
* The return value is the disposition.
*/
sctp_disposition_t
sctp_sf_do_9_2_start_shutdown
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_chunk_t
*
reply
;
...
...
@@ -3236,7 +3482,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(const sctp_endpoint_t *ep,
/* Set the transport for the SHUTDOWN chunk and the timeout for the
* T2-shutdown timer.
*/
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SETUP_T2
,
SCTP_CHUNK
(
reply
));
/* It shall then start the T2-shutdown timer */
...
...
@@ -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
;
}
...
...
@@ -3413,7 +3658,7 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const sctp_endpoint_t *ep,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_GEN_SACK
,
SCTP_FORCE
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_GEN_SACK
,
SCTP_FORCE
());
return
SCTP_DISPOSITION_CONSUME
;
}
...
...
@@ -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,16 +3804,44 @@ 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
* the user. So this routine looks same as sctp_sf_do_9_2_prm_shutdown().
*/
sctp_disposition_t
sctp_sf_autoclose_timer_expire
(
const
sctp_endpoint_t
*
ep
,
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
const
sctp_association_t
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
{
int
disposition
;
...
...
@@ -3583,11 +3856,16 @@ 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
,
arg
,
commands
);
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
...
...
@@ -4,36 +4,36 @@
* Copyright (c) 2001 International Business Machines, Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc.
*
*
* This file is part of the SCTP kernel reference Implementation
*
*
* These are the state tables for the SCTP state machine.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@us.ibm.com>
...
...
@@ -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
,
...
...
@@ -71,7 +72,7 @@ sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
return
sctp_chunk_event_lookup
(
event_subtype
.
chunk
,
state
);
break
;
case
SCTP_EVENT_T_TIMEOUT
:
DO_LOOKUP
(
SCTP_EVENT_TIMEOUT_MAX
,
timeout
,
DO_LOOKUP
(
SCTP_EVENT_TIMEOUT_MAX
,
timeout
,
timeout_event_table
);
break
;
...
...
@@ -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"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_ESTABLISHED */
\
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{.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"}, \
}
#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_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore
"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore
"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore
"}, \
/* SCTP_STATE_ESTABLISHED */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore
"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore
"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_t5_timer_expire, .name = "sctp_sf_t5_timer_expire
"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore
"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{
fn: sctp_sf_not_impl, name: "sctp_sf_not_impl
"}, \
{
.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
);
...
...
@@ -121,7 +119,7 @@ int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
/* Disallow binding twice. */
if
(
!
sctp_sk
(
sk
)
->
ep
->
base
.
bind_addr
.
port
)
retval
=
sctp_do_bind
(
sk
,
(
sockaddr_storage_t
*
)
uaddr
,
retval
=
sctp_do_bind
(
sk
,
(
sockaddr_storage_t
*
)
uaddr
,
addr_len
);
else
retval
=
-
EINVAL
;
...
...
@@ -317,7 +315,7 @@ static int sctp_do_bind(struct sock *sk, sockaddr_storage_t *newaddr, int addr_l
/* Unprotected by locks. Call only with socket lock sk->lock held! See
* sctp_bindx() for a lock-protected call.
*/
*/
static
int
__sctp_bindx
(
struct
sock
*
sk
,
struct
sockaddr_storage
*
addrs
,
int
addrcnt
,
int
flags
)
...
...
@@ -326,11 +324,11 @@ 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
:
case
BINDX_ADD_ADDR
:
retval
=
sctp_bindx_add
(
sk
,
addrs
,
addrcnt
);
break
;
...
...
@@ -411,7 +409,7 @@ int sctp_bindx_add(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
sctp_bindx_rem
(
sk
,
addrs
,
cnt
);
return
retval
;
}
}
}
/* Notify the peer(s), assuming we have (an) association(s).
* FIXME: for UDP, we have a 1-1-many mapping amongst sk, ep and asoc,
...
...
@@ -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
||
...
...
@@ -781,7 +778,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
memcpy
(
&
to
,
msg
->
msg_name
,
msg
->
msg_namelen
);
SCTP_DEBUG_PRINTK
(
"Just memcpy'd. msg_name is "
"0x%x:%u.
\n
"
,
"0x%x:%u.
\n
"
,
to
.
v4
.
sin_addr
.
s_addr
,
to
.
v4
.
sin_port
);
to
.
v4
.
sin_port
=
ntohs
(
to
.
v4
.
sin_port
);
...
...
@@ -823,14 +820,14 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
}
else
{
/* For a peeled-off socket, ignore any associd specified by
* the user with SNDRCVINFO.
*/
*/
if
(
SCTP_SOCKET_UDP_HIGH_BANDWIDTH
==
sp
->
type
)
{
if
(
list_empty
(
&
ep
->
asocs
))
{
err
=
-
EINVAL
;
goto
out_unlock
;
}
asoc
=
list_entry
(
ep
->
asocs
.
next
,
sctp_association_t
,
asocs
);
asocs
);
}
else
if
(
associd
)
{
asoc
=
sctp_id2assoc
(
sk
,
associd
);
}
...
...
@@ -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
)
{
...
...
@@ -988,7 +984,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
/* If the user didn't specify SNDRCVINFO, make up one with
* some defaults.
*/
default_sinfo
.
sinfo_stream
=
asoc
->
defaults
.
stream
;
default_sinfo
.
sinfo_stream
=
asoc
->
defaults
.
stream
;
default_sinfo
.
sinfo_ppid
=
asoc
->
defaults
.
ppid
;
sinfo
=
&
default_sinfo
;
}
...
...
@@ -1011,7 +1007,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
/* FIXME: This looks wrong so I'll comment out.
* We should be able to use this same technique for
* primary address override! --jgrimm
*/
*/
/* If the user gave us an address, copy it in. */
if (msg->msg_name) {
chunk->transport = sctp_assoc_lookup_paddr(asoc, &to);
...
...
@@ -1025,7 +1021,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
/* Copy the message from the user. */
err
=
sctp_user_addto_chunk
(
chunk
,
msg_len
,
msg
->
msg_iov
);
if
(
err
<
0
)
goto
out_free
;
goto
out_free
;
SCTP_DEBUG_PRINTK
(
"Copied message to chunk: %p.
\n
"
,
chunk
);
...
...
@@ -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
;
...
...
@@ -1332,7 +1329,7 @@ static struct sock *sctp_accept(struct sock *sk, int flags, int *err)
{
int
error
=
-
EOPNOTSUPP
;
*
err
=
error
;
*
err
=
error
;
return
NULL
;
}
...
...
@@ -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
;
}
...
...
@@ -1974,7 +1970,7 @@ int sctp_inet_listen(struct socket *sock, int backlog)
err
=
-
EINVAL
;
if
(
sock
->
state
!=
SS_UNCONNECTED
)
goto
out
;
switch
(
sock
->
type
)
{
switch
(
sock
->
type
)
{
case
SOCK_SEQPACKET
:
err
=
sctp_seqpacket_listen
(
sk
,
backlog
);
break
;
...
...
@@ -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
);
...
...
@@ -2127,7 +2123,7 @@ static int sctp_autobind(struct sock *sk)
switch
(
sk
->
family
)
{
case
PF_INET
:
autoaddr
.
v4
.
sin_family
=
AF_INET
;
autoaddr
.
v4
.
sin_addr
.
s_addr
=
INADDR_ANY
;
autoaddr
.
v4
.
sin_addr
.
s_addr
=
INADDR_ANY
;
autoaddr
.
v4
.
sin_port
=
htons
(
inet_sk
(
sk
)
->
num
);
addr_len
=
sizeof
(
struct
sockaddr_in
);
break
;
...
...
@@ -2202,7 +2198,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
return
-
EINVAL
;
}
/* Should we parse this header or ignore? */
/* Should we parse this header or ignore? */
if
(
cmsg
->
cmsg_level
!=
IPPROTO_SCTP
)
continue
;
...
...
@@ -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
;
...
...
@@ -2590,7 +2551,7 @@ static int sctp_wait_for_sndbuf(sctp_association_t *asoc, long *timeo_p, int msg
/* Let another process have a go. Since we are going
* to sleep anyway.
*/
*/
sctp_release_sock
(
sk
);
current_timeo
=
schedule_timeout
(
current_timeo
);
sctp_lock_sock
(
sk
);
...
...
net/sctp/transport.c
View file @
dd18325f
...
...
@@ -4,45 +4,45 @@
* Copyright (c) 2001 International Business Machines Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 La Monte H.P. Yarroll
*
*
* This file is part of the SCTP kernel reference Implementation
*
*
* This module provides the abstraction for an SCTP tranport representing
* a remote transport address. For local transport addresses, we just use
* a remote transport address. For local transport addresses, we just use
* sockaddr_storage_t.
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Jon Grimm <jgrimm@us.ibm.com>
* Xingang Guo <xingang.guo@intel.com>
* Hui Huang <hui.huang@nokia.com>
* Sridhar Samudrala <sri@us.ibm.com>
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
...
...
@@ -215,7 +215,7 @@ void sctp_transport_put(sctp_transport_t *transport)
sctp_transport_destroy
(
transport
);
}
/* Update transport's RTO based on the newly calculated RTT. */
/* Update transport's RTO based on the newly calculated RTT. */
void
sctp_transport_update_rto
(
sctp_transport_t
*
tp
,
__u32
rtt
)
{
sctp_protocol_t
*
proto
=
sctp_get_protocol
();
...
...
@@ -263,7 +263,7 @@ void sctp_transport_update_rto(sctp_transport_t *tp, __u32 rtt)
* seconds then it is rounded up to RTO.Min seconds.
*/
if
(
tp
->
rto
<
tp
->
asoc
->
rto_min
)
tp
->
rto
=
tp
->
asoc
->
rto_min
;
tp
->
rto
=
tp
->
asoc
->
rto_min
;
/* 6.3.1 C7) A maximum value may be placed on RTO provided it is
* at least RTO.max seconds.
...
...
@@ -381,13 +381,13 @@ void sctp_transport_lower_cwnd(sctp_transport_t *transport,
break
;
case
SCTP_LOWER_CWND_FAST_RTX
:
/* RFC 2960 7.2.4 Adjust the ssthresh and cwnd of the
* destination address(es) to which the missing DATA chunks
* were last sent, according to the formula described in
/* RFC 2960 7.2.4 Adjust the ssthresh and cwnd of the
* destination address(es) to which the missing DATA chunks
* were last sent, according to the formula described in
* Section 7.2.3.
*
* RFC 2960 7.2.3, sctpimpguide-05 2.9.2 Upon detection of
* packet losses from SACK (see Section 7.2.4), An endpoint
* RFC 2960 7.2.3, sctpimpguide-05 2.9.2 Upon detection of
* packet losses from SACK (see Section 7.2.4), An endpoint
* should do the following:
* ssthresh = max(cwnd/2, 2*MTU)
* cwnd = ssthresh
...
...
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,22 +538,21 @@ 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
,
__u16
flags
,
int
priority
)
sctp_ulpevent_t
*
sctp_ulpevent_make_shutdown_event
(
const
sctp_association_t
*
asoc
,
__u16
flags
,
int
priority
)
{
sctp_ulpevent_t
*
event
;
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
;
...
...
@@ -619,7 +615,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc,
skb
=
skb_clone
(
chunk
->
skb
,
priority
);
if
(
!
skb
)
goto
fail
;
/* First calculate the padding, so we don't inadvertently
* pass up the wrong length to the user.
*
...
...
@@ -645,7 +641,7 @@ sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc,
event
=
(
sctp_ulpevent_t
*
)
skb
->
cb
;
/* Initialize event with flags 0. */
event
=
sctp_ulpevent_init
(
event
,
skb
,
0
);
event
=
sctp_ulpevent_init
(
event
,
skb
,
0
);
if
(
!
event
)
goto
fail_init
;
...
...
@@ -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
;
}
net/sctp/ulpqueue.c
View file @
dd18325f
...
...
@@ -5,38 +5,38 @@
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
*
*
* This abstraction carries sctp events to the ULP (sockets).
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
*
* The SCTP reference implementation is free software;
* you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* The SCTP reference implementation is distributed in the hope that it
*
* The SCTP reference implementation is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* ************************
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Boston, MA 02111-1307, USA.
*
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
*
*
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
* Written or modified by:
* Written or modified by:
* Jon Grimm <jgrimm@us.ibm.com>
* La Monte H.P. Yarroll <piggy@acm.org>
* Sridhar Samudrala <sri@us.ibm.com>
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
...
...
@@ -131,7 +131,7 @@ int sctp_ulpqueue_tail_data(sctp_ulpqueue_t *ulpq, sctp_chunk_t *chunk,
int
priority
)
{
struct
sk_buff_head
temp
;
sctp_data_chunk_t
*
hdr
;
sctp_data_chunk_t
*
hdr
;
sctp_ulpevent_t
*
event
;
hdr
=
(
sctp_data_chunk_t
*
)
chunk
->
chunk_hdr
;
...
...
@@ -157,7 +157,7 @@ int sctp_ulpqueue_tail_data(sctp_ulpqueue_t *ulpq, sctp_chunk_t *chunk,
event
=
sctp_ulpqueue_order
(
ulpq
,
event
);
}
/* Send event to the ULP. */
if
(
event
)
sctp_ulpqueue_tail_event
(
ulpq
,
event
);
...
...
@@ -449,7 +449,7 @@ static inline sctp_ulpevent_t *sctp_ulpqueue_order(sctp_ulpqueue_t *ulpq,
/* Check if this message needs ordering. */
if
(
SCTP_DATA_UNORDERED
&
event
->
chunk_flags
)
return
event
;
return
event
;
/* Note: The stream ID must be verified before this routine. */
sid
=
event
->
sndrcvinfo
.
sinfo_stream
;
...
...
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