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
f5633ef0
Commit
f5633ef0
authored
Jun 20, 2003
by
Jon Grimm
Browse files
Options
Browse Files
Download
Plain Diff
Hand merge.
parents
58acfd93
ec7bf6c1
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
808 additions
and
376 deletions
+808
-376
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+24
-19
include/net/sctp/structs.h
include/net/sctp/structs.h
+53
-23
include/net/sctp/user.h
include/net/sctp/user.h
+5
-0
net/sctp/associola.c
net/sctp/associola.c
+16
-19
net/sctp/bind_addr.c
net/sctp/bind_addr.c
+1
-3
net/sctp/input.c
net/sctp/input.c
+18
-16
net/sctp/ipv6.c
net/sctp/ipv6.c
+9
-0
net/sctp/objcnt.c
net/sctp/objcnt.c
+2
-0
net/sctp/proc.c
net/sctp/proc.c
+159
-0
net/sctp/protocol.c
net/sctp/protocol.c
+126
-80
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+16
-10
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+2
-1
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+44
-27
net/sctp/sm_statetable.c
net/sctp/sm_statetable.c
+2
-55
net/sctp/socket.c
net/sctp/socket.c
+312
-98
net/sctp/sysctl.c
net/sctp/sysctl.c
+12
-14
net/sctp/transport.c
net/sctp/transport.c
+7
-11
No files found.
include/net/sctp/sctp.h
View file @
f5633ef0
...
...
@@ -119,12 +119,10 @@
*/
/*
* sctp
_
protocol.c
* sctp
/
protocol.c
*/
extern
struct
sctp_protocol
sctp_proto
;
extern
struct
sock
*
sctp_get_ctl_sock
(
void
);
extern
int
sctp_copy_local_addr_list
(
struct
sctp_protocol
*
,
struct
sctp_bind_addr
*
,
extern
int
sctp_copy_local_addr_list
(
struct
sctp_bind_addr
*
,
sctp_scope_t
,
int
gfp
,
int
flags
);
extern
struct
sctp_pf
*
sctp_get_pf_specific
(
sa_family_t
family
);
extern
int
sctp_register_pf
(
struct
sctp_pf
*
,
sa_family_t
);
...
...
@@ -275,6 +273,7 @@ extern atomic_t sctp_dbg_objcnt_assoc;
extern
atomic_t
sctp_dbg_objcnt_transport
;
extern
atomic_t
sctp_dbg_objcnt_chunk
;
extern
atomic_t
sctp_dbg_objcnt_bind_addr
;
extern
atomic_t
sctp_dbg_objcnt_bind_bucket
;
extern
atomic_t
sctp_dbg_objcnt_addr
;
extern
atomic_t
sctp_dbg_objcnt_ssnmap
;
extern
atomic_t
sctp_dbg_objcnt_datamsg
;
...
...
@@ -418,6 +417,10 @@ static inline __s32 sctp_jitter(__u32 rto)
static
__u32
sctp_rand
;
__s32
ret
;
/* Avoid divide by zero. */
if
(
!
rto
)
rto
=
1
;
sctp_rand
+=
jiffies
;
sctp_rand
^=
(
sctp_rand
<<
12
);
sctp_rand
^=
(
sctp_rand
>>
20
);
...
...
@@ -448,7 +451,7 @@ static inline int sctp_frag_point(const struct sctp_opt *sp, int pmtu)
* there is room for a param header too.
*/
#define sctp_walk_params(pos, chunk, member)\
_sctp_walk_params((pos), (chunk),
ntohs((chunk)->chunk_hdr.length
), member)
_sctp_walk_params((pos), (chunk),
WORD_ROUND(ntohs((chunk)->chunk_hdr.length)
), member)
#define _sctp_walk_params(pos, chunk, end, member)\
for (pos.v = chunk->member;\
...
...
@@ -456,6 +459,18 @@ for (pos.v = chunk->member;\
pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)); \
pos.v += WORD_ROUND(ntohs(pos.p->length)))
#define sctp_walk_errors(err, chunk_hdr)\
_sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length))
#define _sctp_walk_errors(err, chunk_hdr, end)\
for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
sizeof(sctp_chunkhdr_t));\
(void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\
(void *)err <= (void *)chunk_hdr + end - \
WORD_ROUND(ntohs(err->length));\
err = (sctp_errhdr_t *)((void *)err + \
WORD_ROUND(ntohs(err->length))))
/* Round an int up to the next multiple of 4. */
#define WORD_ROUND(s) (((s)+3)&~3)
...
...
@@ -491,12 +506,6 @@ void sctp_put_port(struct sock *sk);
/* Static inline functions. */
/* Return the SCTP protocol structure. */
static
inline
struct
sctp_protocol
*
sctp_get_protocol
(
void
)
{
return
&
sctp_proto
;
}
/* Convert from an IP version number to an Address Family symbol. */
static
inline
int
ipver2af
(
__u8
ipver
)
{
...
...
@@ -524,24 +533,21 @@ static inline int sctp_sanity_check(void)
/* This is the hash function for the SCTP port hash table. */
static
inline
int
sctp_phashfn
(
__u16
lport
)
{
struct
sctp_protocol
*
sctp_proto
=
sctp_get_protocol
();
return
(
lport
&
(
sctp_proto
->
port_hashsize
-
1
));
return
(
lport
&
(
sctp_port_hashsize
-
1
));
}
/* This is the hash function for the endpoint hash table. */
static
inline
int
sctp_ep_hashfn
(
__u16
lport
)
{
struct
sctp_protocol
*
sctp_proto
=
sctp_get_protocol
();
return
(
lport
&
(
sctp_proto
->
ep_hashsize
-
1
));
return
(
lport
&
(
sctp_ep_hashsize
-
1
));
}
/* This is the hash function for the association hash table. */
static
inline
int
sctp_assoc_hashfn
(
__u16
lport
,
__u16
rport
)
{
struct
sctp_protocol
*
sctp_proto
=
sctp_get_protocol
();
int
h
=
(
lport
<<
16
)
+
rport
;
h
^=
h
>>
8
;
return
(
h
&
(
sctp_
proto
->
assoc_hashsize
-
1
));
return
(
h
&
(
sctp_assoc_hashsize
-
1
));
}
/* This is the hash function for the association hash table. This is
...
...
@@ -550,10 +556,9 @@ static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport)
*/
static
inline
int
sctp_vtag_hashfn
(
__u16
lport
,
__u16
rport
,
__u32
vtag
)
{
struct
sctp_protocol
*
sctp_proto
=
sctp_get_protocol
();
int
h
=
(
lport
<<
16
)
+
rport
;
h
^=
vtag
;
return
(
h
&
(
sctp_
proto
->
assoc_hashsize
-
1
));
return
(
h
&
(
sctp_assoc_hashsize
-
1
));
}
/* WARNING: Do not change the layout of the members in sctp_sock! */
...
...
include/net/sctp/structs.h
View file @
f5633ef0
...
...
@@ -71,7 +71,7 @@ union sctp_addr {
};
/* Forward declarations for data structures. */
struct
sctp_
protocol
;
struct
sctp_
globals
;
struct
sctp_endpoint
;
struct
sctp_association
;
struct
sctp_transport
;
...
...
@@ -92,28 +92,28 @@ struct sctp_ssnmap;
/* Structures useful for managing bind/connect. */
typedef
struct
sctp_bind_bucket
{
struct
sctp_bind_bucket
{
unsigned
short
port
;
unsigned
short
fastreuse
;
struct
sctp_bind_bucket
*
next
;
struct
sctp_bind_bucket
**
pprev
;
struct
sock
*
sk
;
}
sctp_bind_bucket_t
;
};
typedef
struct
sctp_bind_hashbucket
{
struct
sctp_bind_hashbucket
{
spinlock_t
lock
;
struct
sctp_bind_bucket
*
chain
;
}
sctp_bind_hashbucket_t
;
};
/* Used for hashing all associations. */
typedef
struct
sctp_hashbucket
{
struct
sctp_hashbucket
{
rwlock_t
lock
;
struct
sctp_ep_common
*
chain
;
}
sctp_hashbucket_t
__attribute__
((
__aligned__
(
8
)));
}
__attribute__
((
__aligned__
(
8
)));
/* The SCTP
protocol
structure. */
struct
sctp_protocol
{
/* The SCTP
globals
structure. */
extern
struct
sctp_globals
{
/* RFC2960 Section 14. Suggested SCTP Protocol Parameter Values
*
* The following protocol parameters are RECOMMENDED:
...
...
@@ -167,17 +167,17 @@ struct sctp_protocol {
/* This is the hash of all endpoints. */
int
ep_hashsize
;
s
ctp_hashbucket_
t
*
ep_hashbucket
;
s
truct
sctp_hashbucke
t
*
ep_hashbucket
;
/* This is the hash of all associations. */
int
assoc_hashsize
;
s
ctp_hashbucket_
t
*
assoc_hashbucket
;
s
truct
sctp_hashbucke
t
*
assoc_hashbucket
;
/* This is the sctp port control hash. */
int
port_hashsize
;
int
port_rover
;
spinlock_t
port_alloc_lock
;
/* Protects port_rover. */
s
ctp_bind_hashbucket_
t
*
port_hashtable
;
s
truct
sctp_bind_hashbucke
t
*
port_hashtable
;
/* This is the global local address list.
* We actively maintain this complete list of interfaces on
...
...
@@ -187,8 +187,33 @@ struct sctp_protocol {
*/
struct
list_head
local_addr_list
;
spinlock_t
local_addr_lock
;
};
}
sctp_globals
;
#define sctp_rto_initial (sctp_globals.rto_initial)
#define sctp_rto_min (sctp_globals.rto_min)
#define sctp_rto_max (sctp_globals.rto_max)
#define sctp_rto_alpha (sctp_globals.rto_alpha)
#define sctp_rto_beta (sctp_globals.rto_beta)
#define sctp_max_burst (sctp_globals.max_burst)
#define sctp_valid_cookie_life (sctp_globals.valid_cookie_life)
#define sctp_cookie_preserve_enable (sctp_globals.cookie_preserve_enable)
#define sctp_max_retrans_association (sctp_globals.max_retrans_association)
#define sctp_max_retrans_path (sctp_globals.max_retrans_path)
#define sctp_max_retrans_init (sctp_globals.max_retrans_init)
#define sctp_hb_interval (sctp_globals.hb_interval)
#define sctp_max_instreams (sctp_globals.max_instreams)
#define sctp_max_outstreams (sctp_globals.max_outstreams)
#define sctp_address_families (sctp_globals.address_families)
#define sctp_ep_hashsize (sctp_globals.ep_hashsize)
#define sctp_ep_hashbucket (sctp_globals.ep_hashbucket)
#define sctp_assoc_hashsize (sctp_globals.assoc_hashsize)
#define sctp_assoc_hashbucket (sctp_globals.assoc_hashbucket)
#define sctp_port_hashsize (sctp_globals.port_hashsize)
#define sctp_port_rover (sctp_globals.port_rover)
#define sctp_port_alloc_lock (sctp_globals.port_alloc_lock)
#define sctp_port_hashtable (sctp_globals.port_hashtable)
#define sctp_local_addr_list (sctp_globals.local_addr_list)
#define sctp_local_addr_lock (sctp_globals.local_addr_lock)
/*
* Pointers to address related SCTP functions.
...
...
@@ -239,7 +264,9 @@ struct sctp_af {
int
(
*
is_any
)
(
const
union
sctp_addr
*
);
int
(
*
available
)
(
const
union
sctp_addr
*
);
int
(
*
skb_iif
)
(
const
struct
sk_buff
*
sk
);
int
(
*
is_ce
)
(
const
struct
sk_buff
*
sk
);
int
(
*
is_ce
)
(
const
struct
sk_buff
*
sk
);
void
(
*
seq_dump_addr
)(
struct
seq_file
*
seq
,
union
sctp_addr
*
addr
);
__u16
net_header_len
;
int
sockaddr_len
;
sa_family_t
sa_family
;
...
...
@@ -289,6 +316,10 @@ struct sctp_opt {
/* Various Socket Options. */
__u16
default_stream
;
__u32
default_ppid
;
__u16
default_flags
;
__u32
default_context
;
__u32
default_timetolive
;
struct
sctp_initmsg
initmsg
;
struct
sctp_rtoinfo
rtoinfo
;
struct
sctp_paddrparams
paddrparam
;
...
...
@@ -461,7 +492,7 @@ struct sctp_datamsg {
/* Reference counting. */
atomic_t
refcnt
;
/* When is this message no longer interesting to the peer? */
unsigned
long
expires_at
;
unsigned
long
expires_at
;
/* Did the messenge fail to send? */
int
send_error
;
char
send_failed
;
...
...
@@ -1492,13 +1523,12 @@ struct sctp_association {
*/
int
counters
[
SCTP_NUMBER_COUNTERS
];
struct
{
__u16
stream
;
__u16
flags
;
__u32
ppid
;
__u32
context
;
__u32
timetolive
;
}
defaults
;
/* Default send parameters. */
__u16
default_stream
;
__u16
default_flags
;
__u32
default_ppid
;
__u32
default_context
;
__u32
default_timetolive
;
/* This tracks outbound ssn for a given stream. */
struct
sctp_ssnmap
*
ssnmap
;
...
...
include/net/sctp/user.h
View file @
f5633ef0
...
...
@@ -485,6 +485,11 @@ struct sctp_paddrinfo {
__u32
spinfo_mtu
;
};
/* Peer addresses's state. */
enum
sctp_spinfo_state
{
SCTP_INACTIVE
,
SCTP_ACTIVE
,
};
/*
* 7.1.1 Retransmission Timeout Parameters (SCTP_RTOINFO)
...
...
net/sctp/associola.c
View file @
f5633ef0
...
...
@@ -96,7 +96,6 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
int
gfp
)
{
struct
sctp_opt
*
sp
;
struct
sctp_protocol
*
proto
=
sctp_get_protocol
();
int
i
;
/* Retrieve the SCTP per socket area. */
...
...
@@ -129,26 +128,26 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
asoc
->
state_timestamp
=
jiffies
;
/* Set things that have constant value. */
asoc
->
cookie_life
.
tv_sec
=
sctp_
proto
.
valid_cookie_life
/
HZ
;
asoc
->
cookie_life
.
tv_usec
=
(
sctp_
proto
.
valid_cookie_life
%
HZ
)
*
asoc
->
cookie_life
.
tv_sec
=
sctp_valid_cookie_life
/
HZ
;
asoc
->
cookie_life
.
tv_usec
=
(
sctp_valid_cookie_life
%
HZ
)
*
1000000L
/
HZ
;
asoc
->
pmtu
=
0
;
asoc
->
frag_point
=
0
;
/* Initialize the default association max_retrans and RTO values. */
asoc
->
max_retrans
=
proto
->
max_retrans_association
;
asoc
->
rto_initial
=
proto
->
rto_initial
;
asoc
->
rto_max
=
proto
->
rto_max
;
asoc
->
rto_min
=
proto
->
rto_min
;
asoc
->
max_retrans
=
sctp_
max_retrans_association
;
asoc
->
rto_initial
=
sctp_
rto_initial
;
asoc
->
rto_max
=
sctp_
rto_max
;
asoc
->
rto_min
=
sctp_
rto_min
;
asoc
->
overall_error_threshold
=
0
;
asoc
->
overall_error_threshold
=
asoc
->
max_retrans
;
asoc
->
overall_error_count
=
0
;
/* Initialize the maximum mumber of new data packets that can be sent
* in a burst.
*/
asoc
->
max_burst
=
proto
->
max_burst
;
asoc
->
max_burst
=
sctp_
max_burst
;
/* Copy things from the endpoint. */
for
(
i
=
SCTP_EVENT_TIMEOUT_NONE
;
i
<
SCTP_NUM_TIMEOUT_TYPES
;
++
i
)
{
...
...
@@ -277,6 +276,12 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
asoc
->
autoclose
=
sp
->
autoclose
;
asoc
->
default_stream
=
sp
->
default_stream
;
asoc
->
default_ppid
=
sp
->
default_ppid
;
asoc
->
default_flags
=
sp
->
default_flags
;
asoc
->
default_context
=
sp
->
default_context
;
asoc
->
default_timetolive
=
sp
->
default_timetolive
;
return
asoc
;
fail_init:
...
...
@@ -478,16 +483,8 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
peer
->
partial_bytes_acked
=
0
;
peer
->
flight_size
=
0
;
peer
->
error_threshold
=
peer
->
max_retrans
;
/* Update the overall error threshold value of the association
* taking the new peer's error threshold into account.
*/
asoc
->
overall_error_threshold
=
min
(
asoc
->
overall_error_threshold
+
peer
->
error_threshold
,
asoc
->
max_retrans
);
/* By default, enable heartbeat for peer address. */
peer
->
hb_allowed
=
1
;
...
...
@@ -550,12 +547,12 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
/* Record the transition on the transport. */
switch
(
command
)
{
case
SCTP_TRANSPORT_UP
:
transport
->
active
=
1
;
transport
->
active
=
SCTP_ACTIVE
;
spc_state
=
ADDRESS_AVAILABLE
;
break
;
case
SCTP_TRANSPORT_DOWN
:
transport
->
active
=
0
;
transport
->
active
=
SCTP_INACTIVE
;
spc_state
=
ADDRESS_UNREACHABLE
;
break
;
...
...
net/sctp/bind_addr.c
View file @
f5633ef0
...
...
@@ -329,12 +329,10 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
union
sctp_addr
*
addr
,
sctp_scope_t
scope
,
int
gfp
,
int
flags
)
{
struct
sctp_protocol
*
proto
=
sctp_get_protocol
();
int
error
=
0
;
if
(
sctp_is_any
(
addr
))
{
error
=
sctp_copy_local_addr_list
(
proto
,
dest
,
scope
,
gfp
,
flags
);
error
=
sctp_copy_local_addr_list
(
dest
,
scope
,
gfp
,
flags
);
}
else
if
(
sctp_in_scope
(
addr
,
scope
))
{
/* Now that the address is in scope, check to see if
* the address type is supported by local sock as
...
...
net/sctp/input.c
View file @
f5633ef0
...
...
@@ -503,9 +503,10 @@ int sctp_rcv_ootb(struct sk_buff *skb)
goto
discard
;
if
(
SCTP_CID_ERROR
==
ch
->
type
)
{
err
=
(
sctp_errhdr_t
*
)(
ch
+
sizeof
(
sctp_chunkhdr_t
));
if
(
SCTP_ERROR_STALE_COOKIE
==
err
->
cause
)
goto
discard
;
sctp_walk_errors
(
err
,
ch
)
{
if
(
SCTP_ERROR_STALE_COOKIE
==
err
->
cause
)
goto
discard
;
}
}
ch
=
(
sctp_chunkhdr_t
*
)
ch_end
;
...
...
@@ -522,12 +523,12 @@ void __sctp_hash_endpoint(struct sctp_endpoint *ep)
{
struct
sctp_ep_common
**
epp
;
struct
sctp_ep_common
*
epb
;
s
ctp_hashbucket_
t
*
head
;
s
truct
sctp_hashbucke
t
*
head
;
epb
=
&
ep
->
base
;
epb
->
hashent
=
sctp_ep_hashfn
(
epb
->
bind_addr
.
port
);
head
=
&
sctp_
proto
.
ep_hashbucket
[
epb
->
hashent
];
head
=
&
sctp_ep_hashbucket
[
epb
->
hashent
];
sctp_write_lock
(
&
head
->
lock
);
epp
=
&
head
->
chain
;
...
...
@@ -550,14 +551,14 @@ void sctp_hash_endpoint(struct sctp_endpoint *ep)
/* Remove endpoint from the hash table. */
void
__sctp_unhash_endpoint
(
struct
sctp_endpoint
*
ep
)
{
s
ctp_hashbucket_
t
*
head
;
s
truct
sctp_hashbucke
t
*
head
;
struct
sctp_ep_common
*
epb
;
epb
=
&
ep
->
base
;
epb
->
hashent
=
sctp_ep_hashfn
(
epb
->
bind_addr
.
port
);
head
=
&
sctp_
proto
.
ep_hashbucket
[
epb
->
hashent
];
head
=
&
sctp_ep_hashbucket
[
epb
->
hashent
];
sctp_write_lock
(
&
head
->
lock
);
...
...
@@ -582,13 +583,13 @@ void sctp_unhash_endpoint(struct sctp_endpoint *ep)
/* Look up an endpoint. */
struct
sctp_endpoint
*
__sctp_rcv_lookup_endpoint
(
const
union
sctp_addr
*
laddr
)
{
s
ctp_hashbucket_
t
*
head
;
s
truct
sctp_hashbucke
t
*
head
;
struct
sctp_ep_common
*
epb
;
struct
sctp_endpoint
*
ep
;
int
hash
;
hash
=
sctp_ep_hashfn
(
laddr
->
v4
.
sin_port
);
head
=
&
sctp_
proto
.
ep_hashbucket
[
hash
];
head
=
&
sctp_ep_hashbucket
[
hash
];
read_lock
(
&
head
->
lock
);
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
ep
=
sctp_ep
(
epb
);
...
...
@@ -619,14 +620,14 @@ void __sctp_hash_established(struct sctp_association *asoc)
{
struct
sctp_ep_common
**
epp
;
struct
sctp_ep_common
*
epb
;
s
ctp_hashbucket_
t
*
head
;
s
truct
sctp_hashbucke
t
*
head
;
epb
=
&
asoc
->
base
;
/* Calculate which chain this entry will belong to. */
epb
->
hashent
=
sctp_assoc_hashfn
(
epb
->
bind_addr
.
port
,
asoc
->
peer
.
port
);
head
=
&
sctp_
proto
.
assoc_hashbucket
[
epb
->
hashent
];
head
=
&
sctp_assoc_hashbucket
[
epb
->
hashent
];
sctp_write_lock
(
&
head
->
lock
);
epp
=
&
head
->
chain
;
...
...
@@ -649,7 +650,7 @@ void sctp_unhash_established(struct sctp_association *asoc)
/* Remove association from the hash table. */
void
__sctp_unhash_established
(
struct
sctp_association
*
asoc
)
{
s
ctp_hashbucket_
t
*
head
;
s
truct
sctp_hashbucke
t
*
head
;
struct
sctp_ep_common
*
epb
;
epb
=
&
asoc
->
base
;
...
...
@@ -657,7 +658,7 @@ void __sctp_unhash_established(struct sctp_association *asoc)
epb
->
hashent
=
sctp_assoc_hashfn
(
epb
->
bind_addr
.
port
,
asoc
->
peer
.
port
);
head
=
&
sctp_
proto
.
assoc_hashbucket
[
epb
->
hashent
];
head
=
&
sctp_assoc_hashbucket
[
epb
->
hashent
];
sctp_write_lock
(
&
head
->
lock
);
...
...
@@ -677,7 +678,7 @@ struct sctp_association *__sctp_lookup_association(
const
union
sctp_addr
*
peer
,
struct
sctp_transport
**
pt
)
{
s
ctp_hashbucket_
t
*
head
;
s
truct
sctp_hashbucke
t
*
head
;
struct
sctp_ep_common
*
epb
;
struct
sctp_association
*
asoc
;
struct
sctp_transport
*
transport
;
...
...
@@ -687,7 +688,7 @@ struct sctp_association *__sctp_lookup_association(
* have wildcards anyways.
*/
hash
=
sctp_assoc_hashfn
(
local
->
v4
.
sin_port
,
peer
->
v4
.
sin_port
);
head
=
&
sctp_
proto
.
assoc_hashbucket
[
hash
];
head
=
&
sctp_assoc_hashbucket
[
hash
];
read_lock
(
&
head
->
lock
);
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
asoc
=
sctp_assoc
(
epb
);
...
...
@@ -766,6 +767,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
sctp_chunkhdr_t
*
ch
;
union
sctp_params
params
;
sctp_init_chunk_t
*
init
;
struct
sctp_transport
*
transport
;
ch
=
(
sctp_chunkhdr_t
*
)
skb
->
data
;
...
...
@@ -805,7 +807,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
continue
;
sctp_param2sockaddr
(
paddr
,
params
.
addr
,
ntohs
(
sh
->
source
),
0
);
asoc
=
__sctp_lookup_association
(
laddr
,
paddr
,
transportp
);
asoc
=
__sctp_lookup_association
(
laddr
,
paddr
,
&
transport
);
if
(
asoc
)
return
asoc
;
}
...
...
net/sctp/ipv6.c
View file @
f5633ef0
...
...
@@ -61,6 +61,7 @@
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
#include <linux/random.h>
#include <linux/seq_file.h>
#include <net/protocol.h>
#include <net/tcp.h>
...
...
@@ -578,6 +579,13 @@ static int sctp_v6_is_ce(const struct sk_buff *skb)
return
*
((
__u32
*
)(
skb
->
nh
.
ipv6h
))
&
htonl
(
1
<<
20
);
}
/* Dump the v6 addr to the seq file. */
static
void
sctp_v6_seq_dump_addr
(
struct
seq_file
*
seq
,
union
sctp_addr
*
addr
)
{
seq_printf
(
seq
,
"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
,
NIP6
(
addr
->
v6
.
sin6_addr
));
}
/* Initialize a PF_INET6 socket msg_name. */
static
void
sctp_inet6_msgname
(
char
*
msgname
,
int
*
addr_len
)
{
...
...
@@ -840,6 +848,7 @@ static struct sctp_af sctp_ipv6_specific = {
.
available
=
sctp_v6_available
,
.
skb_iif
=
sctp_v6_skb_iif
,
.
is_ce
=
sctp_v6_is_ce
,
.
seq_dump_addr
=
sctp_v6_seq_dump_addr
,
.
net_header_len
=
sizeof
(
struct
ipv6hdr
),
.
sockaddr_len
=
sizeof
(
struct
sockaddr_in6
),
.
sa_family
=
AF_INET6
,
...
...
net/sctp/objcnt.c
View file @
f5633ef0
...
...
@@ -53,6 +53,7 @@ SCTP_DBG_OBJCNT(ep);
SCTP_DBG_OBJCNT
(
transport
);
SCTP_DBG_OBJCNT
(
assoc
);
SCTP_DBG_OBJCNT
(
bind_addr
);
SCTP_DBG_OBJCNT
(
bind_bucket
);
SCTP_DBG_OBJCNT
(
chunk
);
SCTP_DBG_OBJCNT
(
addr
);
SCTP_DBG_OBJCNT
(
ssnmap
);
...
...
@@ -68,6 +69,7 @@ sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
SCTP_DBG_OBJCNT_ENTRY
(
transport
),
SCTP_DBG_OBJCNT_ENTRY
(
chunk
),
SCTP_DBG_OBJCNT_ENTRY
(
bind_addr
),
SCTP_DBG_OBJCNT_ENTRY
(
bind_bucket
),
SCTP_DBG_OBJCNT_ENTRY
(
addr
),
SCTP_DBG_OBJCNT_ENTRY
(
ssnmap
),
SCTP_DBG_OBJCNT_ENTRY
(
datamsg
),
...
...
net/sctp/proc.c
View file @
f5633ef0
...
...
@@ -128,3 +128,162 @@ void sctp_snmp_proc_exit(void)
{
remove_proc_entry
(
"snmp"
,
proc_net_sctp
);
}
/* Dump local addresses of an association/endpoint. */
static
void
sctp_seq_dump_local_addrs
(
struct
seq_file
*
seq
,
struct
sctp_ep_common
*
epb
)
{
struct
list_head
*
pos
;
struct
sockaddr_storage_list
*
laddr
;
union
sctp_addr
*
addr
;
struct
sctp_af
*
af
;
list_for_each
(
pos
,
&
epb
->
bind_addr
.
address_list
)
{
laddr
=
list_entry
(
pos
,
struct
sockaddr_storage_list
,
list
);
addr
=
(
union
sctp_addr
*
)
&
laddr
->
a
;
af
=
sctp_get_af_specific
(
addr
->
sa
.
sa_family
);
af
->
seq_dump_addr
(
seq
,
addr
);
}
}
/* Dump remote addresses of an association. */
static
void
sctp_seq_dump_remote_addrs
(
struct
seq_file
*
seq
,
struct
sctp_association
*
assoc
)
{
struct
list_head
*
pos
;
struct
sctp_transport
*
transport
;
union
sctp_addr
*
addr
;
struct
sctp_af
*
af
;
list_for_each
(
pos
,
&
assoc
->
peer
.
transport_addr_list
)
{
transport
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
addr
=
(
union
sctp_addr
*
)
&
transport
->
ipaddr
;
af
=
sctp_get_af_specific
(
addr
->
sa
.
sa_family
);
af
->
seq_dump_addr
(
seq
,
addr
);
}
}
/* Display sctp endpoints (/proc/net/sctp/eps). */
static
int
sctp_eps_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
struct
sctp_hashbucket
*
head
;
struct
sctp_ep_common
*
epb
;
struct
sctp_endpoint
*
ep
;
struct
sock
*
sk
;
int
hash
;
seq_printf
(
seq
,
" ENDPT SOCK STY SST HBKT LPORT LADDRS
\n
"
);
for
(
hash
=
0
;
hash
<
sctp_ep_hashsize
;
hash
++
)
{
head
=
&
sctp_ep_hashbucket
[
hash
];
read_lock
(
&
head
->
lock
);
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
ep
=
sctp_ep
(
epb
);
sk
=
epb
->
sk
;
seq_printf
(
seq
,
"%8p %8p %-3d %-3d %-4d %-5d "
,
ep
,
sk
,
sctp_sk
(
sk
)
->
type
,
sk
->
state
,
hash
,
epb
->
bind_addr
.
port
);
sctp_seq_dump_local_addrs
(
seq
,
epb
);
seq_printf
(
seq
,
"
\n
"
);
}
read_unlock
(
&
head
->
lock
);
}
return
0
;
}
/* Initialize the seq file operations for 'eps' object. */
static
int
sctp_eps_seq_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
sctp_eps_seq_show
,
NULL
);
}
static
struct
file_operations
sctp_eps_seq_fops
=
{
.
open
=
sctp_eps_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
/* Set up the proc fs entry for 'eps' object. */
int
__init
sctp_eps_proc_init
(
void
)
{
struct
proc_dir_entry
*
p
;
p
=
create_proc_entry
(
"eps"
,
S_IRUGO
,
proc_net_sctp
);
if
(
!
p
)
return
-
ENOMEM
;
p
->
proc_fops
=
&
sctp_eps_seq_fops
;
return
0
;
}
/* Cleanup the proc fs entry for 'eps' object. */
void
sctp_eps_proc_exit
(
void
)
{
remove_proc_entry
(
"eps"
,
proc_net_sctp
);
}
/* Display sctp associations (/proc/net/sctp/assocs). */
static
int
sctp_assocs_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
struct
sctp_hashbucket
*
head
;
struct
sctp_ep_common
*
epb
;
struct
sctp_association
*
assoc
;
struct
sock
*
sk
;
int
hash
;
seq_printf
(
seq
,
" ASSOC SOCK STY SST ST HBKT LPORT RPORT "
"LADDRS <-> RADDRS
\n
"
);
for
(
hash
=
0
;
hash
<
sctp_assoc_hashsize
;
hash
++
)
{
head
=
&
sctp_assoc_hashbucket
[
hash
];
read_lock
(
&
head
->
lock
);
for
(
epb
=
head
->
chain
;
epb
;
epb
=
epb
->
next
)
{
assoc
=
sctp_assoc
(
epb
);
sk
=
epb
->
sk
;
seq_printf
(
seq
,
"%8p %8p %-3d %-3d %-2d %-4d %-5d %-5d "
,
assoc
,
sk
,
sctp_sk
(
sk
)
->
type
,
sk
->
state
,
assoc
->
state
,
hash
,
epb
->
bind_addr
.
port
,
assoc
->
peer
.
port
);
sctp_seq_dump_local_addrs
(
seq
,
epb
);
seq_printf
(
seq
,
"<-> "
);
sctp_seq_dump_remote_addrs
(
seq
,
assoc
);
seq_printf
(
seq
,
"
\n
"
);
}
read_unlock
(
&
head
->
lock
);
}
return
0
;
}
/* Initialize the seq file operations for 'assocs' object. */
static
int
sctp_assocs_seq_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
sctp_assocs_seq_show
,
NULL
);
}
static
struct
file_operations
sctp_assocs_seq_fops
=
{
.
open
=
sctp_assocs_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
/* Set up the proc fs entry for 'assocs' object. */
int
__init
sctp_assocs_proc_init
(
void
)
{
struct
proc_dir_entry
*
p
;
p
=
create_proc_entry
(
"assocs"
,
S_IRUGO
,
proc_net_sctp
);
if
(
!
p
)
return
-
ENOMEM
;
p
->
proc_fops
=
&
sctp_assocs_seq_fops
;
return
0
;
}
/* Cleanup the proc fs entry for 'assocs' object. */
void
sctp_assocs_proc_exit
(
void
)
{
remove_proc_entry
(
"assocs"
,
proc_net_sctp
);
}
net/sctp/protocol.c
View file @
f5633ef0
This diff is collapsed.
Click to expand it.
net/sctp/sm_make_chunk.c
View file @
f5633ef0
...
...
@@ -68,6 +68,8 @@
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
extern
kmem_cache_t
*
sctp_chunk_cachep
;
/* What was the inbound interface for this chunk? */
int
sctp_chunk_iif
(
const
struct
sctp_chunk
*
chunk
)
{
...
...
@@ -874,7 +876,7 @@ struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
const
void
*
payload
,
const
size_t
paylen
)
{
struct
sctp_chunk
*
retval
=
sctp_make_chunk
(
asoc
,
SCTP_CID_HEARTBEAT
,
0
,
paylen
);
0
,
paylen
);
if
(
!
retval
)
goto
nodata
;
...
...
@@ -976,7 +978,9 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
const
struct
sctp_association
*
asoc
,
struct
sock
*
sk
)
{
struct
sctp_chunk
*
retval
=
t_new
(
struct
sctp_chunk
,
GFP_ATOMIC
);
struct
sctp_chunk
*
retval
;
retval
=
kmem_cache_alloc
(
sctp_chunk_cachep
,
SLAB_ATOMIC
);
if
(
!
retval
)
goto
nodata
;
...
...
@@ -1048,7 +1052,7 @@ const union sctp_addr *sctp_source(const struct sctp_chunk *chunk)
* arguments, reserving enough space for a 'paylen' byte payload.
*/
struct
sctp_chunk
*
sctp_make_chunk
(
const
struct
sctp_association
*
asoc
,
__u8
type
,
__u8
flags
,
int
paylen
)
__u8
type
,
__u8
flags
,
int
paylen
)
{
struct
sctp_chunk
*
retval
;
sctp_chunkhdr_t
*
chunk_hdr
;
...
...
@@ -1075,13 +1079,12 @@ struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
}
retval
->
chunk_hdr
=
chunk_hdr
;
retval
->
chunk_end
=
((
__u8
*
)
chunk_hdr
)
+
sizeof
(
s
ctp_chunkhdr_t
);
retval
->
chunk_end
=
((
__u8
*
)
chunk_hdr
)
+
sizeof
(
s
truct
sctp_chunkhdr
);
/* Set the skb to the belonging sock for accounting. */
skb
->
sk
=
sk
;
return
retval
;
nodata:
return
NULL
;
}
...
...
@@ -1090,12 +1093,11 @@ struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
/* Release the memory occupied by a chunk. */
static
void
sctp_chunk_destroy
(
struct
sctp_chunk
*
chunk
)
{
/* Free the chunk skb data and the SCTP_chunk stub itself. */
dev_kfree_skb
(
chunk
->
skb
);
kfree
(
chunk
);
SCTP_DBG_OBJCNT_DEC
(
chunk
);
kmem_cache_free
(
sctp_chunk_cachep
,
chunk
);
}
/* Possibly, free the chunk. */
...
...
@@ -1728,8 +1730,12 @@ int sctp_verify_init(const struct sctp_association *asoc,
sctp_walk_params
(
param
,
peer_init
,
init_hdr
.
params
)
{
if
(
!
sctp_verify_param
(
asoc
,
param
,
cid
,
chunk
,
errp
))
return
0
;
if
(
!
sctp_verify_param
(
asoc
,
param
,
cid
,
chunk
,
errp
))
{
if
(
SCTP_PARAM_HOST_NAME_ADDRESS
==
param
.
p
->
type
)
return
0
;
else
return
1
;
}
}
/* for (loop through all parameters) */
...
...
@@ -1907,7 +1913,7 @@ int sctp_process_param(struct sctp_association *asoc, union sctp_params param,
break
;
case
SCTP_PARAM_COOKIE_PRESERVATIVE
:
if
(
!
sctp_
proto
.
cookie_preserve_enable
)
if
(
!
sctp_cookie_preserve_enable
)
break
;
stale
=
ntohl
(
param
.
life
->
lifespan_increment
);
...
...
net/sctp/sm_sideeffect.c
View file @
f5633ef0
...
...
@@ -415,7 +415,8 @@ static void sctp_cmd_init_failed(sctp_cmd_seq_t *commands,
struct
sctp_ulpevent
*
event
;
event
=
sctp_ulpevent_make_assoc_change
(
asoc
,
0
,
SCTP_CANT_STR_ASSOC
,
0
,
0
,
0
,
GFP_ATOMIC
);
(
__u16
)
error
,
0
,
0
,
GFP_ATOMIC
);
if
(
event
)
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
...
...
net/sctp/sm_statefuns.c
View file @
f5633ef0
...
...
@@ -738,7 +738,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
{
struct
sctp_transport
*
transport
=
(
struct
sctp_transport
*
)
arg
;
if
(
asoc
->
overall_error_count
>
=
asoc
->
overall_error_threshold
)
{
if
(
asoc
->
overall_error_count
>
asoc
->
overall_error_threshold
)
{
/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_U32
(
SCTP_ERROR_NO_ERROR
));
...
...
@@ -1238,7 +1238,6 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
* parameter type.
*/
sctp_addto_chunk
(
repl
,
len
,
unk_param
);
sctp_chunk_free
(
err_chunk
);
}
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_NEW_ASOC
,
SCTP_ASOC
(
new_asoc
));
...
...
@@ -1788,24 +1787,17 @@ sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
struct
sctp_chunk
*
chunk
=
arg
;
sctp_errhdr_t
*
err
;
err
=
(
sctp_errhdr_t
*
)(
chunk
->
skb
->
data
);
/* If we have gotten too many failures, give up. */
if
(
1
+
asoc
->
counters
[
SCTP_COUNTER_INIT_ERROR
]
>
asoc
->
max_init_attempts
)
{
/* INIT_FAILED will issue an ulpevent. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_INIT_FAILED
,
SCTP_U32
(
err
->
cause
));
return
SCTP_DISPOSITION_DELETE_TCB
;
}
/* Process the error here */
switch
(
err
->
cause
)
{
case
SCTP_ERROR_STALE_COOKIE
:
return
sctp_sf_do_5_2_6_stale
(
ep
,
asoc
,
type
,
arg
,
commands
);
default:
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
/* FUTURE FIXME: When PR-SCTP related and other optional
* parms are emitted, this will have to change to handle multiple
* errors.
*/
sctp_walk_errors
(
err
,
chunk
->
chunk_hdr
)
{
if
(
SCTP_ERROR_STALE_COOKIE
==
err
->
cause
)
return
sctp_sf_do_5_2_6_stale
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
}
/*
...
...
@@ -2067,6 +2059,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
struct
sctp_chunk
*
chunk
=
arg
;
sctp_shutdownhdr_t
*
sdh
;
sctp_disposition_t
disposition
;
struct
sctp_ulpevent
*
ev
;
/* Convert the elaborate header. */
sdh
=
(
sctp_shutdownhdr_t
*
)
chunk
->
skb
->
data
;
...
...
@@ -2097,12 +2090,28 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
arg
,
commands
);
}
if
(
SCTP_DISPOSITION_NOMEM
==
disposition
)
goto
out
;
/* - verify, by checking the Cumulative TSN Ack field of the
* chunk, that all its outstanding DATA chunks have been
* received by the SHUTDOWN sender.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_PROCESS_CTSN
,
SCTP_U32
(
chunk
->
subh
.
shutdown_hdr
->
cum_tsn_ack
));
/* API 5.3.1.5 SCTP_SHUTDOWN_EVENT
* When a peer sends a SHUTDOWN, SCTP delivers this notification to
* inform the application that it should cease sending data.
*/
ev
=
sctp_ulpevent_make_shutdown_event
(
asoc
,
0
,
GFP_ATOMIC
);
if
(
!
ev
)
{
disposition
=
SCTP_DISPOSITION_NOMEM
;
goto
out
;
}
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_EVENT_ULP
,
SCTP_ULPEVENT
(
ev
));
out:
return
disposition
;
}
...
...
@@ -2334,7 +2343,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
if
(
af
&&
af
->
is_ce
(
chunk
->
skb
)
&&
asoc
->
peer
.
ecn_capable
)
{
/* Do real work as sideffect. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ECN_CE
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ECN_CE
,
SCTP_U32
(
tsn
));
}
}
...
...
@@ -2375,7 +2384,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
* PMTU. In cases, such as loopback, this might be a rather
* large spill over.
*/
if
(
!
asoc
->
rwnd
||
asoc
->
rwnd_over
||
if
(
!
asoc
->
rwnd
||
asoc
->
rwnd_over
||
(
datalen
>
asoc
->
rwnd
+
asoc
->
frag_point
))
{
/* If this is the next TSN, consider reneging to make
...
...
@@ -2594,7 +2603,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
if
(
af
&&
af
->
is_ce
(
chunk
->
skb
)
&&
asoc
->
peer
.
ecn_capable
)
{
/* Do real work as sideffect. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ECN_CE
,
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ECN_CE
,
SCTP_U32
(
tsn
));
}
}
...
...
@@ -2740,6 +2749,9 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
/* Pull the SACK chunk from the data buffer */
sackh
=
sctp_sm_pull_sack
(
chunk
);
/* Was this a bogus SACK? */
if
(
!
sackh
)
return
sctp_sf_pdiscard
(
ep
,
asoc
,
type
,
arg
,
commands
);
chunk
->
subh
.
sack_hdr
=
sackh
;
ctsn
=
ntohl
(
sackh
->
cum_tsn_ack
);
...
...
@@ -4406,22 +4418,27 @@ sctp_disposition_t sctp_sf_timer_ignore(const struct sctp_endpoint *ep,
********************************************************************/
/* Pull the SACK chunk based on the SACK header. */
s
ctp_sackhdr_t
*
sctp_sm_pull_sack
(
struct
sctp_chunk
*
chunk
)
s
truct
sctp_sackhdr
*
sctp_sm_pull_sack
(
struct
sctp_chunk
*
chunk
)
{
sctp_sackhdr_t
*
sack
;
struct
sctp_sackhdr
*
sack
;
unsigned
int
len
;
__u16
num_blocks
;
__u16
num_dup_tsns
;
/*
FIXME:
Protect ourselves from reading too far into
/* Protect ourselves from reading too far into
* the skb from a bogus sender.
*/
sack
=
(
sctp_sackhdr_t
*
)
chunk
->
skb
->
data
;
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_sackhdr_t
));
sack
=
(
struct
sctp_sackhdr
*
)
chunk
->
skb
->
data
;
num_blocks
=
ntohs
(
sack
->
num_gap_ack_blocks
);
num_dup_tsns
=
ntohs
(
sack
->
num_dup_tsns
);
len
=
sizeof
(
struct
sctp_sackhdr
);
len
=
(
num_blocks
+
num_dup_tsns
)
*
sizeof
(
__u32
);
if
(
len
>
chunk
->
skb
->
len
)
return
NULL
;
skb_pull
(
chunk
->
skb
,
len
);
skb_pull
(
chunk
->
skb
,
(
num_blocks
+
num_dup_tsns
)
*
sizeof
(
__u32
));
return
sack
;
}
...
...
net/sctp/sm_statetable.c
View file @
f5633ef0
...
...
@@ -436,51 +436,6 @@ sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NU
TYPE_SCTP_SHUTDOWN_COMPLETE
,
};
/* state_fn_t chunk_event_table[][] */
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"
},
/* SCTP_STATE_CLOSED */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_WAIT */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_ECHOED */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_ESTABLISHED */
{.
fn
=
sctp_sf_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"
},
/* SCTP_STATE_SHUTDOWN_SENT */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_RECEIVED */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
};
/* 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"
},
/* SCTP_STATE_CLOSED */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_WAIT */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_COOKIE_ECHOED */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_ESTABLISHED */
{.
fn
=
sctp_sf_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"
},
/* SCTP_STATE_SHUTDOWN_SENT */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_RECEIVED */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
{.
fn
=
sctp_sf_discard_chunk
,
.
name
=
"sctp_sf_discard_chunk"
},
};
/* chunk asconf_ack */
static
sctp_sm_table_entry_t
chunk_event_table_unknown
[
SCTP_STATE_NUM_STATES
]
=
{
...
...
@@ -783,7 +738,7 @@ sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STA
/* SCTP_STATE_ESTABLISHED */
\
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{.fn = sctp_sf_t
imer_ignore, .name = "sctp_sf_timer_igno
re"}, \
{.fn = sctp_sf_t
5_timer_expire, .name = "sctp_sf_t5_timer_expi
re"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{.fn = sctp_sf_t5_timer_expire, .name = "sctp_sf_t5_timer_expire"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
...
...
@@ -877,13 +832,5 @@ sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t stat
return
&
chunk_event_table
[
cid
][
state
];
}
switch
(
cid
)
{
case
SCTP_CID_ASCONF
:
return
&
chunk_event_table_asconf
[
state
];
case
SCTP_CID_ASCONF_ACK
:
return
&
chunk_event_table_asconf_ack
[
state
];
default:
return
&
chunk_event_table_unknown
[
state
];
}
return
&
chunk_event_table_unknown
[
state
];
}
net/sctp/socket.c
View file @
f5633ef0
This diff is collapsed.
Click to expand it.
net/sctp/sysctl.c
View file @
f5633ef0
...
...
@@ -42,13 +42,11 @@
#include <net/sctp/structs.h>
#include <linux/sysctl.h>
extern
struct
sctp_protocol
sctp_proto
;
static
ctl_table
sctp_table
[]
=
{
{
.
ctl_name
=
NET_SCTP_RTO_INITIAL
,
.
procname
=
"rto_initial"
,
.
data
=
&
sctp_
proto
.
rto_initial
,
.
data
=
&
sctp_rto_initial
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec_jiffies
,
...
...
@@ -57,7 +55,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_RTO_MIN
,
.
procname
=
"rto_min"
,
.
data
=
&
sctp_
proto
.
rto_min
,
.
data
=
&
sctp_rto_min
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec_jiffies
,
...
...
@@ -66,7 +64,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_RTO_MAX
,
.
procname
=
"rto_max"
,
.
data
=
&
sctp_
proto
.
rto_max
,
.
data
=
&
sctp_rto_max
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec_jiffies
,
...
...
@@ -75,7 +73,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_VALID_COOKIE_LIFE
,
.
procname
=
"valid_cookie_life"
,
.
data
=
&
sctp_
proto
.
valid_cookie_life
,
.
data
=
&
sctp_valid_cookie_life
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec_jiffies
,
...
...
@@ -84,7 +82,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_MAX_BURST
,
.
procname
=
"max_burst"
,
.
data
=
&
sctp_
proto
.
max_burst
,
.
data
=
&
sctp_max_burst
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
...
...
@@ -92,7 +90,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_ASSOCIATION_MAX_RETRANS
,
.
procname
=
"association_max_retrans"
,
.
data
=
&
sctp_
proto
.
max_retrans_association
,
.
data
=
&
sctp_max_retrans_association
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
...
...
@@ -100,7 +98,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_PATH_MAX_RETRANS
,
.
procname
=
"path_max_retrans"
,
.
data
=
&
sctp_
proto
.
max_retrans_path
,
.
data
=
&
sctp_max_retrans_path
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
...
...
@@ -108,7 +106,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_MAX_INIT_RETRANSMITS
,
.
procname
=
"max_init_retransmits"
,
.
data
=
&
sctp_
proto
.
max_retrans_init
,
.
data
=
&
sctp_max_retrans_init
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
...
...
@@ -116,7 +114,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_HB_INTERVAL
,
.
procname
=
"hb_interval"
,
.
data
=
&
sctp_
proto
.
hb_interval
,
.
data
=
&
sctp_hb_interval
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec_jiffies
,
...
...
@@ -125,7 +123,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_PRESERVE_ENABLE
,
.
procname
=
"cookie_preserve_enable"
,
.
data
=
&
sctp_
proto
.
cookie_preserve_enable
,
.
data
=
&
sctp_cookie_preserve_enable
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec_jiffies
,
...
...
@@ -134,7 +132,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_RTO_ALPHA
,
.
procname
=
"rto_alpha_exp_divisor"
,
.
data
=
&
sctp_
proto
.
rto_alpha
,
.
data
=
&
sctp_rto_alpha
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
...
...
@@ -142,7 +140,7 @@ static ctl_table sctp_table[] = {
{
.
ctl_name
=
NET_SCTP_RTO_BETA
,
.
procname
=
"rto_beta_exp_divisor"
,
.
data
=
&
sctp_
proto
.
rto_beta
,
.
data
=
&
sctp_rto_beta
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
...
...
net/sctp/transport.c
View file @
f5633ef0
...
...
@@ -82,8 +82,6 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
const
union
sctp_addr
*
addr
,
int
gfp
)
{
struct
sctp_protocol
*
proto
=
sctp_get_protocol
();
/* Copy in the address. */
peer
->
ipaddr
=
*
addr
;
peer
->
af_specific
=
sctp_get_af_specific
(
addr
->
sa
.
sa_family
);
...
...
@@ -99,7 +97,7 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
* parameter 'RTO.Initial'.
*/
peer
->
rtt
=
0
;
peer
->
rto
=
proto
->
rto_initial
;
peer
->
rto
=
sctp_
rto_initial
;
peer
->
rttvar
=
0
;
peer
->
srtt
=
0
;
peer
->
rto_pending
=
0
;
...
...
@@ -108,11 +106,11 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
peer
->
last_time_used
=
jiffies
;
peer
->
last_time_ecne_reduced
=
jiffies
;
peer
->
active
=
1
;
peer
->
active
=
SCTP_ACTIVE
;
peer
->
hb_allowed
=
0
;
/* Initialize the default path max_retrans. */
peer
->
max_retrans
=
proto
->
max_retrans_path
;
peer
->
max_retrans
=
sctp_
max_retrans_path
;
peer
->
error_threshold
=
0
;
peer
->
error_count
=
0
;
...
...
@@ -272,8 +270,6 @@ void sctp_transport_put(struct sctp_transport *transport)
/* Update transport's RTO based on the newly calculated RTT. */
void
sctp_transport_update_rto
(
struct
sctp_transport
*
tp
,
__u32
rtt
)
{
struct
sctp_protocol
*
proto
=
sctp_get_protocol
();
/* Check for valid transport. */
SCTP_ASSERT
(
tp
,
"NULL transport"
,
return
);
...
...
@@ -292,10 +288,10 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
* For example, assuming the default value of RTO.Alpha of
* 1/8, rto_alpha would be expressed as 3.
*/
tp
->
rttvar
=
tp
->
rttvar
-
(
tp
->
rttvar
>>
proto
->
rto_beta
)
+
((
abs
(
tp
->
srtt
-
rtt
))
>>
proto
->
rto_beta
);
tp
->
srtt
=
tp
->
srtt
-
(
tp
->
srtt
>>
proto
->
rto_alpha
)
+
(
rtt
>>
proto
->
rto_alpha
);
tp
->
rttvar
=
tp
->
rttvar
-
(
tp
->
rttvar
>>
sctp_
rto_beta
)
+
((
abs
(
tp
->
srtt
-
rtt
))
>>
sctp_
rto_beta
);
tp
->
srtt
=
tp
->
srtt
-
(
tp
->
srtt
>>
sctp_
rto_alpha
)
+
(
rtt
>>
sctp_
rto_alpha
);
}
else
{
/* 6.3.1 C2) When the first RTT measurement R is made, set
* SRTT <- R, RTTVAR <- R/2.
...
...
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