Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
bd23ad70
Commit
bd23ad70
authored
Jan 19, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-lksctp.bkbits.net/lksctp-2.5.work
into nuts.ninka.net:/disk1/davem/BK/net-2.6
parents
d8baa0e0
3ac3019b
Changes
17
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
788 additions
and
95 deletions
+788
-95
include/linux/sctp.h
include/linux/sctp.h
+2
-1
include/linux/sysctl.h
include/linux/sysctl.h
+1
-0
include/net/sctp/constants.h
include/net/sctp/constants.h
+1
-3
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+4
-2
include/net/sctp/sm.h
include/net/sctp/sm.h
+21
-6
include/net/sctp/structs.h
include/net/sctp/structs.h
+11
-0
net/sctp/associola.c
net/sctp/associola.c
+47
-0
net/sctp/input.c
net/sctp/input.c
+3
-6
net/sctp/output.c
net/sctp/output.c
+1
-2
net/sctp/outqueue.c
net/sctp/outqueue.c
+1
-1
net/sctp/protocol.c
net/sctp/protocol.c
+3
-0
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+408
-10
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+8
-7
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+175
-19
net/sctp/sm_statetable.c
net/sctp/sm_statetable.c
+8
-6
net/sctp/socket.c
net/sctp/socket.c
+86
-32
net/sctp/sysctl.c
net/sctp/sysctl.c
+8
-0
No files found.
include/linux/sctp.h
View file @
bd23ad70
...
@@ -439,12 +439,13 @@ typedef enum {
...
@@ -439,12 +439,13 @@ typedef enum {
* 0x0101 Operation Refused Due to Resource Shortage.
* 0x0101 Operation Refused Due to Resource Shortage.
* 0x0102 Request to Delete Source IP Address.
* 0x0102 Request to Delete Source IP Address.
* 0x0103 Association Aborted due to illegal ASCONF-ACK
* 0x0103 Association Aborted due to illegal ASCONF-ACK
* 0x0104 Request refused - no authorization.
*/
*/
SCTP_ERROR_DEL_LAST_IP
=
__constant_htons
(
0x0100
),
SCTP_ERROR_DEL_LAST_IP
=
__constant_htons
(
0x0100
),
SCTP_ERROR_RSRC_LOW
=
__constant_htons
(
0x0101
),
SCTP_ERROR_RSRC_LOW
=
__constant_htons
(
0x0101
),
SCTP_ERROR_DEL_SRC_IP
=
__constant_htons
(
0x0102
),
SCTP_ERROR_DEL_SRC_IP
=
__constant_htons
(
0x0102
),
SCTP_ERROR_ASCONF_ACK
=
__constant_htons
(
0x0103
),
SCTP_ERROR_ASCONF_ACK
=
__constant_htons
(
0x0103
),
SCTP_ERROR_REQ_REFUSED
=
__constant_htons
(
0x0104
)
}
sctp_error_t
;
}
sctp_error_t
;
...
...
include/linux/sysctl.h
View file @
bd23ad70
...
@@ -580,6 +580,7 @@ enum {
...
@@ -580,6 +580,7 @@ enum {
NET_SCTP_HB_INTERVAL
=
10
,
NET_SCTP_HB_INTERVAL
=
10
,
NET_SCTP_PRESERVE_ENABLE
=
11
,
NET_SCTP_PRESERVE_ENABLE
=
11
,
NET_SCTP_MAX_BURST
=
12
,
NET_SCTP_MAX_BURST
=
12
,
NET_SCTP_ADDIP_ENABLE
=
13
,
};
};
/* /proc/sys/net/bridge */
/* /proc/sys/net/bridge */
...
...
include/net/sctp/constants.h
View file @
bd23ad70
/* SCTP kernel reference Implementation
/* SCTP kernel reference Implementation
* (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001-2002 International Business Machines Corp.
*
*
* This file is part of the SCTP kernel reference Implementation
* This file is part of the SCTP kernel reference Implementation
*
*
...
@@ -75,8 +75,6 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
...
@@ -75,8 +75,6 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
#define SCTP_NUM_BASE_CHUNK_TYPES (SCTP_CID_BASE_MAX + 1)
#define SCTP_NUM_BASE_CHUNK_TYPES (SCTP_CID_BASE_MAX + 1)
#define SCTP_NUM_CHUNK_TYPES (SCTP_NUM_BASE_CHUNKTYPES + 2)
#define SCTP_NUM_CHUNK_TYPES (SCTP_NUM_BASE_CHUNKTYPES + 2)
#define SCTP_CID_ADDIP_MIN SCTP_CID_ASCONF
#define SCTP_CID_ADDIP_MAX SCTP_CID_ASCONF_ACK
#define SCTP_NUM_ADDIP_CHUNK_TYPES 2
#define SCTP_NUM_ADDIP_CHUNK_TYPES 2
/* These are the different flavours of event. */
/* These are the different flavours of event. */
...
...
include/net/sctp/sctp.h
View file @
bd23ad70
...
@@ -115,8 +115,10 @@
...
@@ -115,8 +115,10 @@
#define SCTP_STATIC static
#define SCTP_STATIC static
#endif
#endif
#define MSECS_TO_JIFFIES(msec) (msec * HZ / 1000)
#define MSECS_TO_JIFFIES(msec) \
#define JIFFIES_TO_MSECS(jiff) (jiff * 1000 / HZ)
(((msec / 1000) * HZ) + ((msec % 1000) * HZ) / 1000)
#define JIFFIES_TO_MSECS(jiff) \
(((jiff / HZ) * 1000) + ((jiff % HZ) * 1000) / HZ)
/*
/*
* Function declarations.
* Function declarations.
...
...
include/net/sctp/sm.h
View file @
bd23ad70
...
@@ -268,15 +268,15 @@ struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
...
@@ -268,15 +268,15 @@ struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
struct
sctp_chunk
*
sctp_make_asconf_update_ip
(
struct
sctp_association
*
,
struct
sctp_chunk
*
sctp_make_asconf_update_ip
(
struct
sctp_association
*
,
union
sctp_addr
*
,
union
sctp_addr
*
,
struct
sockaddr
*
,
struct
sockaddr
*
,
int
,
int
);
int
,
__u16
);
struct
sctp_chunk
*
sctp_make_asconf_set_prim
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
sctp_make_asconf_set_prim
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
addr
);
union
sctp_addr
*
addr
);
struct
sctp_chunk
*
sctp_make_asconf_ack
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
sctp_make_asconf_ack
(
const
struct
sctp_association
*
asoc
,
int
serial
,
int
vparam_len
);
__u32
serial
,
int
vparam_len
);
struct
sctp_chunk
*
sctp_process_asconf
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
sctp_process_asconf
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
asconf
,
struct
sctp_chunk
*
asconf
);
int
vparam_len
);
int
sctp_process_asconf_ack
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
asconf_ack
);
void
sctp_chunk_assign_tsn
(
struct
sctp_chunk
*
);
void
sctp_chunk_assign_tsn
(
struct
sctp_chunk
*
);
void
sctp_chunk_assign_ssn
(
struct
sctp_chunk
*
);
void
sctp_chunk_assign_ssn
(
struct
sctp_chunk
*
);
...
@@ -431,6 +431,21 @@ static inline int SSN_lte(__u16 s, __u16 t)
...
@@ -431,6 +431,21 @@ static inline int SSN_lte(__u16 s, __u16 t)
return
(((
s
)
==
(
t
))
||
(((
s
)
-
(
t
))
&
SSN_SIGN_BIT
));
return
(((
s
)
==
(
t
))
||
(((
s
)
-
(
t
))
&
SSN_SIGN_BIT
));
}
}
/*
* ADDIP 3.1.1
* The valid range of Serial Number is from 0 to 4294967295 (2**32 - 1). Serial
* Numbers wrap back to 0 after reaching 4294967295.
*/
enum
{
ADDIP_SERIAL_SIGN_BIT
=
(
1
<<
31
)
};
static
inline
int
ADDIP_SERIAL_gte
(
__u16
s
,
__u16
t
)
{
return
(((
s
)
==
(
t
))
||
(((
t
)
-
(
s
))
&
ADDIP_SERIAL_SIGN_BIT
));
}
/* Run sctp_add_cmd() generating a BUG() if there is a failure. */
/* Run sctp_add_cmd() generating a BUG() if there is a failure. */
static
inline
void
sctp_add_cmd_sf
(
sctp_cmd_seq_t
*
seq
,
sctp_verb_t
verb
,
sctp_arg_t
obj
)
static
inline
void
sctp_add_cmd_sf
(
sctp_cmd_seq_t
*
seq
,
sctp_verb_t
verb
,
sctp_arg_t
obj
)
{
{
...
...
include/net/sctp/structs.h
View file @
bd23ad70
...
@@ -190,6 +190,9 @@ extern struct sctp_globals {
...
@@ -190,6 +190,9 @@ extern struct sctp_globals {
*/
*/
struct
list_head
local_addr_list
;
struct
list_head
local_addr_list
;
spinlock_t
local_addr_lock
;
spinlock_t
local_addr_lock
;
/* Flag to indicate if addip is enabled. */
int
addip_enable
;
}
sctp_globals
;
}
sctp_globals
;
#define sctp_rto_initial (sctp_globals.rto_initial)
#define sctp_rto_initial (sctp_globals.rto_initial)
...
@@ -217,6 +220,7 @@ extern struct sctp_globals {
...
@@ -217,6 +220,7 @@ extern struct sctp_globals {
#define sctp_port_hashtable (sctp_globals.port_hashtable)
#define sctp_port_hashtable (sctp_globals.port_hashtable)
#define sctp_local_addr_list (sctp_globals.local_addr_list)
#define sctp_local_addr_list (sctp_globals.local_addr_list)
#define sctp_local_addr_lock (sctp_globals.local_addr_lock)
#define sctp_local_addr_lock (sctp_globals.local_addr_lock)
#define sctp_addip_enable (sctp_globals.addip_enable)
/* SCTP Socket type: UDP or TCP style. */
/* SCTP Socket type: UDP or TCP style. */
typedef
enum
{
typedef
enum
{
...
@@ -1397,6 +1401,11 @@ struct sctp_association {
...
@@ -1397,6 +1401,11 @@ struct sctp_association {
/* Does peer support ADDIP? */
/* Does peer support ADDIP? */
__u8
asconf_capable
;
__u8
asconf_capable
;
/* This mask is used to disable sending the ASCONF chunk
* with specified parameter to peer.
*/
__u16
addip_disabled_mask
;
struct
sctp_inithdr
i
;
struct
sctp_inithdr
i
;
int
cookie_len
;
int
cookie_len
;
void
*
cookie
;
void
*
cookie
;
...
@@ -1708,6 +1717,8 @@ int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
...
@@ -1708,6 +1717,8 @@ int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
struct
sctp_transport
*
sctp_assoc_add_peer
(
struct
sctp_association
*
,
struct
sctp_transport
*
sctp_assoc_add_peer
(
struct
sctp_association
*
,
const
union
sctp_addr
*
address
,
const
union
sctp_addr
*
address
,
const
int
gfp
);
const
int
gfp
);
void
sctp_assoc_del_peer
(
struct
sctp_association
*
asoc
,
const
union
sctp_addr
*
addr
);
void
sctp_assoc_control_transport
(
struct
sctp_association
*
,
void
sctp_assoc_control_transport
(
struct
sctp_association
*
,
struct
sctp_transport
*
,
struct
sctp_transport
*
,
sctp_transport_cmd_t
,
sctp_sn_error_t
);
sctp_transport_cmd_t
,
sctp_sn_error_t
);
...
...
net/sctp/associola.c
View file @
bd23ad70
...
@@ -362,6 +362,14 @@ void sctp_association_free(struct sctp_association *asoc)
...
@@ -362,6 +362,14 @@ void sctp_association_free(struct sctp_association *asoc)
asoc
->
eyecatcher
=
0
;
asoc
->
eyecatcher
=
0
;
/* Free any cached ASCONF_ACK chunk. */
if
(
asoc
->
addip_last_asconf_ack
)
sctp_chunk_free
(
asoc
->
addip_last_asconf_ack
);
/* Free any cached ASCONF chunk. */
if
(
asoc
->
addip_last_asconf
)
sctp_chunk_free
(
asoc
->
addip_last_asconf
);
sctp_association_put
(
asoc
);
sctp_association_put
(
asoc
);
}
}
...
@@ -525,6 +533,45 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
...
@@ -525,6 +533,45 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
return
peer
;
return
peer
;
}
}
/* Delete a transport address from an association. */
void
sctp_assoc_del_peer
(
struct
sctp_association
*
asoc
,
const
union
sctp_addr
*
addr
)
{
struct
list_head
*
pos
;
struct
list_head
*
temp
;
struct
sctp_transport
*
peer
=
NULL
;
struct
sctp_transport
*
transport
;
list_for_each_safe
(
pos
,
temp
,
&
asoc
->
peer
.
transport_addr_list
)
{
transport
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
if
(
sctp_cmp_addr_exact
(
addr
,
&
transport
->
ipaddr
))
{
peer
=
transport
;
list_del
(
pos
);
break
;
}
}
/* The address we want delete is not in the association. */
if
(
!
peer
)
return
;
/* Get the first transport of asoc. */
pos
=
asoc
->
peer
.
transport_addr_list
.
next
;
transport
=
list_entry
(
pos
,
struct
sctp_transport
,
transports
);
/* Update any entries that match the peer to be deleted. */
if
(
asoc
->
peer
.
primary_path
==
peer
)
sctp_assoc_set_primary
(
asoc
,
transport
);
if
(
asoc
->
peer
.
active_path
==
peer
)
asoc
->
peer
.
active_path
=
transport
;
if
(
asoc
->
peer
.
retran_path
==
peer
)
asoc
->
peer
.
retran_path
=
transport
;
if
(
asoc
->
peer
.
last_data_from
==
peer
)
asoc
->
peer
.
last_data_from
=
transport
;
sctp_transport_free
(
peer
);
}
/* Lookup a transport by address. */
/* Lookup a transport by address. */
struct
sctp_transport
*
sctp_assoc_lookup_paddr
(
struct
sctp_transport
*
sctp_assoc_lookup_paddr
(
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
...
...
net/sctp/input.c
View file @
bd23ad70
...
@@ -124,16 +124,16 @@ int sctp_rcv(struct sk_buff *skb)
...
@@ -124,16 +124,16 @@ int sctp_rcv(struct sk_buff *skb)
/* Pull up the IP and SCTP headers. */
/* Pull up the IP and SCTP headers. */
__skb_pull
(
skb
,
skb
->
h
.
raw
-
skb
->
data
);
__skb_pull
(
skb
,
skb
->
h
.
raw
-
skb
->
data
);
if
(
skb
->
len
<
sizeof
(
struct
sctphdr
))
if
(
skb
->
len
<
sizeof
(
struct
sctphdr
))
goto
bad_packe
t
;
goto
discard_i
t
;
if
(
sctp_rcv_checksum
(
skb
)
<
0
)
if
(
sctp_rcv_checksum
(
skb
)
<
0
)
goto
bad_packe
t
;
goto
discard_i
t
;
skb_pull
(
skb
,
sizeof
(
struct
sctphdr
));
skb_pull
(
skb
,
sizeof
(
struct
sctphdr
));
family
=
ipver2af
(
skb
->
nh
.
iph
->
version
);
family
=
ipver2af
(
skb
->
nh
.
iph
->
version
);
af
=
sctp_get_af_specific
(
family
);
af
=
sctp_get_af_specific
(
family
);
if
(
unlikely
(
!
af
))
if
(
unlikely
(
!
af
))
goto
bad_packe
t
;
goto
discard_i
t
;
/* Initialize local addresses for lookups. */
/* Initialize local addresses for lookups. */
af
->
from_skb
(
&
src
,
skb
,
1
);
af
->
from_skb
(
&
src
,
skb
,
1
);
...
@@ -223,9 +223,6 @@ int sctp_rcv(struct sk_buff *skb)
...
@@ -223,9 +223,6 @@ int sctp_rcv(struct sk_buff *skb)
sock_put
(
sk
);
sock_put
(
sk
);
return
ret
;
return
ret
;
bad_packet:
SCTP_INC_STATS
(
SctpChecksumErrors
);
discard_it:
discard_it:
kfree_skb
(
skb
);
kfree_skb
(
skb
);
return
ret
;
return
ret
;
...
...
net/sctp/output.c
View file @
bd23ad70
/* SCTP kernel reference Implementation
/* SCTP kernel reference Implementation
* (C) Copyright IBM Corp. 2001, 2004
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2003 International Business Machines, Corp.
*
*
* This file is part of the SCTP kernel reference Implementation
* This file is part of the SCTP kernel reference Implementation
*
*
...
@@ -350,7 +350,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -350,7 +350,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
*/
*/
SCTP_DEBUG_PRINTK
(
"***sctp_transmit_packet***
\n
"
);
SCTP_DEBUG_PRINTK
(
"***sctp_transmit_packet***
\n
"
);
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
)))
{
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
)))
{
if
(
sctp_chunk_is_data
(
chunk
))
{
if
(
sctp_chunk_is_data
(
chunk
))
{
if
(
!
chunk
->
has_tsn
)
{
if
(
!
chunk
->
has_tsn
)
{
...
...
net/sctp/outqueue.c
View file @
bd23ad70
...
@@ -150,7 +150,7 @@ static inline int sctp_cacc_skip_3_1(struct sctp_transport *primary,
...
@@ -150,7 +150,7 @@ static inline int sctp_cacc_skip_3_1(struct sctp_transport *primary,
if
(
!
primary
->
cacc
.
cycling_changeover
)
{
if
(
!
primary
->
cacc
.
cycling_changeover
)
{
if
(
sctp_cacc_skip_3_1_d
(
primary
,
transport
,
count_of_newacks
))
if
(
sctp_cacc_skip_3_1_d
(
primary
,
transport
,
count_of_newacks
))
return
1
;
return
1
;
if
(
sctp_cacc_skip_3_1_f
(
transport
,
count_of_newacks
))
;
if
(
sctp_cacc_skip_3_1_f
(
transport
,
count_of_newacks
))
return
1
;
return
1
;
return
0
;
return
0
;
}
}
...
...
net/sctp/protocol.c
View file @
bd23ad70
...
@@ -1115,6 +1115,9 @@ __init int sctp_init(void)
...
@@ -1115,6 +1115,9 @@ __init int sctp_init(void)
"(established %d bind %d)
\n
"
,
"(established %d bind %d)
\n
"
,
sctp_assoc_hashsize
,
sctp_port_hashsize
);
sctp_assoc_hashsize
,
sctp_port_hashsize
);
/* Disable ADDIP by default. */
sctp_addip_enable
=
0
;
sctp_sysctl_register
();
sctp_sysctl_register
();
INIT_LIST_HEAD
(
&
sctp_address_families
);
INIT_LIST_HEAD
(
&
sctp_address_families
);
...
...
net/sctp/sm_make_chunk.c
View file @
bd23ad70
This diff is collapsed.
Click to expand it.
net/sctp/sm_sideeffect.c
View file @
bd23ad70
/* SCTP kernel reference Implementation
/* SCTP kernel reference Implementation
* (C) Copyright IBM Corp. 2001, 200
3
* (C) Copyright IBM Corp. 2001, 200
4
* Copyright (c) 1999 Cisco, Inc.
* Copyright (c) 1999 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
*
*
...
@@ -663,10 +663,11 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds,
...
@@ -663,10 +663,11 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds,
struct
sock
*
sk
=
asoc
->
base
.
sk
;
struct
sock
*
sk
=
asoc
->
base
.
sk
;
/* If it is a non-temporary association belonging to a TCP-style
/* If it is a non-temporary association belonging to a TCP-style
* listening socket
, do not free it so that accept() can pick it
* listening socket
that is not closed, do not free it so that accept()
* up later.
*
can pick it
up later.
*/
*/
if
(
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
LISTENING
)
&&
(
!
asoc
->
temp
))
if
(
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
LISTENING
)
&&
(
!
asoc
->
temp
)
&&
(
sk
->
sk_shutdown
!=
SHUTDOWN_MASK
))
return
;
return
;
sctp_unhash_established
(
asoc
);
sctp_unhash_established
(
asoc
);
...
@@ -676,8 +677,8 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds,
...
@@ -676,8 +677,8 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds,
/*
/*
* ADDIP Section 4.1 ASCONF Chunk Procedures
* ADDIP Section 4.1 ASCONF Chunk Procedures
* A4) Start a T-4 RTO timer, using the RTO value of the selected
* A4) Start a T-4 RTO timer, using the RTO value of the selected
* destination address (
normally the primary path; see RFC2960
* destination address (
we use active path instead of primary path just
*
section 6.4 for details).
*
because primary path may be inactive.
*/
*/
static
void
sctp_cmd_setup_t4
(
sctp_cmd_seq_t
*
cmds
,
static
void
sctp_cmd_setup_t4
(
sctp_cmd_seq_t
*
cmds
,
struct
sctp_association
*
asoc
,
struct
sctp_association
*
asoc
,
...
@@ -685,7 +686,7 @@ static void sctp_cmd_setup_t4(sctp_cmd_seq_t *cmds,
...
@@ -685,7 +686,7 @@ static void sctp_cmd_setup_t4(sctp_cmd_seq_t *cmds,
{
{
struct
sctp_transport
*
t
;
struct
sctp_transport
*
t
;
t
=
asoc
->
peer
.
primary
_path
;
t
=
asoc
->
peer
.
active
_path
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T4_RTO
]
=
t
->
rto
;
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_T4_RTO
]
=
t
->
rto
;
chunk
->
transport
=
t
;
chunk
->
transport
=
t
;
}
}
...
...
net/sctp/sm_statefuns.c
View file @
bd23ad70
/* SCTP kernel reference Implementation
/* SCTP kernel reference Implementation
* (C) Copyright IBM Corp. 2001, 200
3
* (C) Copyright IBM Corp. 2001, 200
4
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2002 Intel Corp.
* Copyright (c) 2001-2002 Intel Corp.
...
@@ -46,6 +46,7 @@
...
@@ -46,6 +46,7 @@
* Daisy Chang <daisyc@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
* Ardelle Fan <ardelle.fan@intel.com>
* Ryan Layer <rmlayer@us.ibm.com>
* Ryan Layer <rmlayer@us.ibm.com>
* Kevin Gao <kevin.gao@intel.com>
*
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
* be incorporated into the next SCTP release.
...
@@ -3066,19 +3067,57 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
...
@@ -3066,19 +3067,57 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
return
sctp_sf_shut_8_4_5
(
ep
,
NULL
,
type
,
arg
,
commands
);
return
sctp_sf_shut_8_4_5
(
ep
,
NULL
,
type
,
arg
,
commands
);
}
}
/*
/* ADDIP Section 4.2 Upon reception of an ASCONF Chunk. */
* ADDIP Section 4.2 Upon reception of an ASCONF Chunk
* When an endpoint receive an ASCONF Chunk from the remote peer
* special procedures MAY be needed to identify the association the
* ASCONF Chunk is associated with. To properly find the association
* the following procedures should be L1 to L4 and C1 to C5
*/
sctp_disposition_t
sctp_sf_do_asconf
(
const
struct
sctp_endpoint
*
ep
,
sctp_disposition_t
sctp_sf_do_asconf
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_association
*
asoc
,
const
sctp_subtype_t
type
,
void
*
arg
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
// FIXME: Handle the ASCONF chunk
struct
sctp_chunk
*
chunk
=
arg
;
struct
sctp_chunk
*
asconf_ack
=
NULL
;
sctp_addiphdr_t
*
hdr
;
__u32
serial
;
hdr
=
(
sctp_addiphdr_t
*
)
chunk
->
skb
->
data
;
serial
=
ntohl
(
hdr
->
serial
);
/* ADDIP 4.2 C1) Compare the value of the serial number to the value
* the endpoint stored in a new association variable
* 'Peer-Serial-Number'.
*/
if
(
serial
==
asoc
->
peer
.
addip_serial
+
1
)
{
/* ADDIP 4.2 C2) If the value found in the serial number is
* equal to the ('Peer-Serial-Number' + 1), the endpoint MUST
* do V1-V5.
*/
asconf_ack
=
sctp_process_asconf
((
struct
sctp_association
*
)
asoc
,
chunk
);
if
(
!
asconf_ack
)
return
SCTP_DISPOSITION_NOMEM
;
}
else
if
(
serial
==
asoc
->
peer
.
addip_serial
)
{
/* ADDIP 4.2 C3) If the value found in the serial number is
* equal to the value stored in the 'Peer-Serial-Number'
* IMPLEMENTATION NOTE: As an optimization a receiver may wish
* to save the last ASCONF-ACK for some predetermined period of * time and instead of re-processing the ASCONF (with the same
* serial number) it may just re-transmit the ASCONF-ACK.
*/
if
(
asoc
->
addip_last_asconf_ack
)
asconf_ack
=
asoc
->
addip_last_asconf_ack
;
else
return
SCTP_DISPOSITION_DISCARD
;
}
else
{
/* ADDIP 4.2 C4) Otherwise, the ASCONF Chunk is discarded since
* it must be either a stale packet or from an attacker.
*/
return
SCTP_DISPOSITION_DISCARD
;
}
/* ADDIP 4.2 C5) In both cases C2 and C3 the ASCONF-ACK MUST be sent
* back to the source address contained in the IP header of the ASCONF
* being responded to.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
asconf_ack
));
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
}
}
...
@@ -3092,8 +3131,77 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
...
@@ -3092,8 +3131,77 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
const
sctp_subtype_t
type
,
void
*
arg
,
const
sctp_subtype_t
type
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
// FIXME: Handle the ASCONF-ACK chunk
struct
sctp_chunk
*
asconf_ack
=
arg
;
struct
sctp_chunk
*
last_asconf
=
asoc
->
addip_last_asconf
;
struct
sctp_chunk
*
abort
;
sctp_addiphdr_t
*
addip_hdr
;
__u32
sent_serial
,
rcvd_serial
;
addip_hdr
=
(
sctp_addiphdr_t
*
)
asconf_ack
->
skb
->
data
;
rcvd_serial
=
ntohl
(
addip_hdr
->
serial
);
if
(
last_asconf
)
{
addip_hdr
=
(
sctp_addiphdr_t
*
)
last_asconf
->
subh
.
addip_hdr
;
sent_serial
=
ntohl
(
addip_hdr
->
serial
);
}
else
{
sent_serial
=
asoc
->
addip_serial
-
1
;
}
/* D0) If an endpoint receives an ASCONF-ACK that is greater than or
* equal to the next serial number to be used but no ASCONF chunk is
* outstanding the endpoint MUST ABORT the association. Note that a
* sequence number is greater than if it is no more than 2^^31-1
* larger than the current sequence number (using serial arithmetic).
*/
if
(
ADDIP_SERIAL_gte
(
rcvd_serial
,
sent_serial
+
1
)
&&
!
(
asoc
->
addip_last_asconf
))
{
abort
=
sctp_make_abort
(
asoc
,
asconf_ack
,
sizeof
(
sctp_errhdr_t
));
if
(
abort
)
{
sctp_init_cause
(
abort
,
SCTP_ERROR_ASCONF_ACK
,
NULL
,
0
);
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
abort
));
}
/* We are going to ABORT, so we might as well stop
* processing the rest of the chunks in the packet.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T4_RTO
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_DISCARD_PACKET
,
SCTP_NULL
());
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_U32
(
SCTP_ERROR_ASCONF_ACK
));
SCTP_INC_STATS
(
SctpAborteds
);
SCTP_DEC_STATS
(
SctpCurrEstab
);
return
SCTP_DISPOSITION_ABORT
;
}
if
((
rcvd_serial
==
sent_serial
)
&&
asoc
->
addip_last_asconf
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T4_RTO
));
if
(
!
sctp_process_asconf_ack
((
struct
sctp_association
*
)
asoc
,
asconf_ack
))
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
abort
=
sctp_make_abort
(
asoc
,
asconf_ack
,
sizeof
(
sctp_errhdr_t
));
if
(
abort
)
{
sctp_init_cause
(
abort
,
SCTP_ERROR_RSRC_LOW
,
NULL
,
0
);
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
abort
));
}
/* We are going to ABORT, so we might as well stop
* 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_ASSOC_FAILED
,
SCTP_U32
(
SCTP_ERROR_ASCONF_ACK
));
SCTP_INC_STATS
(
SctpAborteds
);
SCTP_DEC_STATS
(
SctpCurrEstab
);
return
SCTP_DISPOSITION_ABORT
;
}
return
SCTP_DISPOSITION_DISCARD
;
}
}
/*
/*
...
@@ -4269,7 +4377,7 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
...
@@ -4269,7 +4377,7 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
/*
/*
* ADDIP Section 4.1 ASCONF CHunk Procedures
* ADDIP Section 4.1 ASCONF CHunk Procedures
* If the T
-
4 RTO timer expires the endpoint should do B1 to B5
* If the T4 RTO timer expires the endpoint should do B1 to B5
*/
*/
sctp_disposition_t
sctp_sf_t4_timer_expire
(
sctp_disposition_t
sctp_sf_t4_timer_expire
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_endpoint
*
ep
,
...
@@ -4278,7 +4386,55 @@ sctp_disposition_t sctp_sf_t4_timer_expire(
...
@@ -4278,7 +4386,55 @@ sctp_disposition_t sctp_sf_t4_timer_expire(
void
*
arg
,
void
*
arg
,
sctp_cmd_seq_t
*
commands
)
sctp_cmd_seq_t
*
commands
)
{
{
// FIXME: need to handle t4 expire
struct
sctp_chunk
*
chunk
=
asoc
->
addip_last_asconf
;
struct
sctp_transport
*
transport
=
chunk
->
transport
;
/* ADDIP 4.1 B1) Increment the error counters and perform path failure
* detection on the appropriate destination address as defined in
* RFC2960 [5] section 8.1 and 8.2.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_STRIKE
,
SCTP_TRANSPORT
(
transport
));
/* Reconfig T4 timer and transport. */
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_SETUP_T4
,
SCTP_CHUNK
(
chunk
));
/* ADDIP 4.1 B2) Increment the association error counters and perform
* endpoint failure detection on the association as defined in
* RFC2960 [5] section 8.1 and 8.2.
* association error counter is incremented in SCTP_CMD_STRIKE.
*/
if
(
asoc
->
overall_error_count
>=
asoc
->
max_retrans
)
{
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_STOP
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T4_RTO
));
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_ASSOC_FAILED
,
SCTP_U32
(
SCTP_ERROR_NO_ERROR
));
SCTP_INC_STATS
(
SctpAborteds
);
SCTP_INC_STATS
(
SctpCurrEstab
);
return
SCTP_DISPOSITION_ABORT
;
}
/* ADDIP 4.1 B3) Back-off the destination address RTO value to which
* the ASCONF chunk was sent by doubling the RTO timer value.
* This is done in SCTP_CMD_STRIKE.
*/
/* ADDIP 4.1 B4) Re-transmit the ASCONF Chunk last sent and if possible
* choose an alternate destination address (please refer to RFC2960
* [5] section 6.4.1). An endpoint MUST NOT add new parameters to this
* chunk, it MUST be the same (including its serial number) as the last
* ASCONF sent.
*/
sctp_chunk_hold
(
asoc
->
addip_last_asconf
);
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_REPLY
,
SCTP_CHUNK
(
asoc
->
addip_last_asconf
));
/* ADDIP 4.1 B5) Restart the T-4 RTO timer. Note that if a different
* destination is selected, then the RTO used will be that of the new
* destination address.
*/
sctp_add_cmd_sf
(
commands
,
SCTP_CMD_TIMER_RESTART
,
SCTP_TO
(
SCTP_EVENT_TIMEOUT_T4_RTO
));
return
SCTP_DISPOSITION_CONSUME
;
return
SCTP_DISPOSITION_CONSUME
;
}
}
...
...
net/sctp/sm_statetable.c
View file @
bd23ad70
/* SCTP kernel reference Implementation
/* SCTP kernel reference Implementation
* (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2003 International Business Machines, Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 Nokia, Inc.
*
*
...
@@ -921,13 +921,15 @@ const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
...
@@ -921,13 +921,15 @@ const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
if
(
state
>
SCTP_STATE_MAX
)
if
(
state
>
SCTP_STATE_MAX
)
return
&
bug
;
return
&
bug
;
if
(
cid
>=
0
&&
cid
<=
SCTP_CID_BASE_MAX
)
{
if
(
cid
>=
0
&&
cid
<=
SCTP_CID_BASE_MAX
)
return
&
chunk_event_table
[
cid
][
state
];
return
&
chunk_event_table
[
cid
][
state
];
}
if
(
cid
>=
SCTP_CID_ADDIP_MIN
&&
cid
<=
SCTP_CID_ADDIP_MAX
)
{
if
(
sctp_addip_enable
)
{
return
&
addip_chunk_event_table
if
(
cid
==
SCTP_CID_ASCONF
)
[
cid
-
SCTP_CID_ADDIP_MIN
][
state
];
return
&
addip_chunk_event_table
[
0
][
state
];
if
(
cid
==
SCTP_CID_ASCONF_ACK
)
return
&
addip_chunk_event_table
[
1
][
state
];
}
}
return
&
chunk_event_table_unknown
[
state
];
return
&
chunk_event_table_unknown
[
state
];
...
...
net/sctp/socket.c
View file @
bd23ad70
/* SCTP kernel reference Implementation
/* SCTP kernel reference Implementation
* (C) Copyright IBM Corp. 2001, 200
3
* (C) Copyright IBM Corp. 2001, 200
4
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2003 Intel Corp.
* Copyright (c) 2001-2003 Intel Corp.
...
@@ -100,6 +100,8 @@ static int sctp_bindx_add(struct sock *, struct sockaddr *, int);
...
@@ -100,6 +100,8 @@ static int sctp_bindx_add(struct sock *, struct sockaddr *, int);
static
int
sctp_bindx_rem
(
struct
sock
*
,
struct
sockaddr
*
,
int
);
static
int
sctp_bindx_rem
(
struct
sock
*
,
struct
sockaddr
*
,
int
);
static
int
sctp_send_asconf_add_ip
(
struct
sock
*
,
struct
sockaddr
*
,
int
);
static
int
sctp_send_asconf_add_ip
(
struct
sock
*
,
struct
sockaddr
*
,
int
);
static
int
sctp_send_asconf_del_ip
(
struct
sock
*
,
struct
sockaddr
*
,
int
);
static
int
sctp_send_asconf_del_ip
(
struct
sock
*
,
struct
sockaddr
*
,
int
);
static
int
sctp_send_asconf
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
chunk
);
static
int
sctp_do_bind
(
struct
sock
*
,
union
sctp_addr
*
,
int
);
static
int
sctp_do_bind
(
struct
sock
*
,
union
sctp_addr
*
,
int
);
static
int
sctp_autobind
(
struct
sock
*
sk
);
static
int
sctp_autobind
(
struct
sock
*
sk
);
static
void
sctp_sock_migrate
(
struct
sock
*
,
struct
sock
*
,
static
void
sctp_sock_migrate
(
struct
sock
*
,
struct
sock
*
,
...
@@ -150,10 +152,14 @@ struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
...
@@ -150,10 +152,14 @@ struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
{
{
struct
sctp_association
*
addr_asoc
=
NULL
,
*
id_asoc
=
NULL
;
struct
sctp_association
*
addr_asoc
=
NULL
,
*
id_asoc
=
NULL
;
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
union
sctp_addr
*
laddr
=
(
union
sctp_addr
*
)
addr
;
laddr
->
v4
.
sin_port
=
ntohs
(
laddr
->
v4
.
sin_port
);
addr_asoc
=
sctp_endpoint_lookup_assoc
(
sctp_sk
(
sk
)
->
ep
,
addr_asoc
=
sctp_endpoint_lookup_assoc
(
sctp_sk
(
sk
)
->
ep
,
(
union
sctp_addr
*
)
addr
,
(
union
sctp_addr
*
)
addr
,
&
transport
);
&
transport
);
laddr
->
v4
.
sin_port
=
htons
(
laddr
->
v4
.
sin_port
);
if
(
!
addr_asoc
)
if
(
!
addr_asoc
)
return
NULL
;
return
NULL
;
...
@@ -300,6 +306,41 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
...
@@ -300,6 +306,41 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
return
ret
;
return
ret
;
}
}
/* ADDIP Section 4.1.1 Congestion Control of ASCONF Chunks
*
* R1) One and only one ASCONF Chunk MAY be in transit and unacknowledged
* at any one time. If a sender, after sending an ASCONF chunk, decides
* it needs to transfer another ASCONF Chunk, it MUST wait until the
* ASCONF-ACK Chunk returns from the previous ASCONF Chunk before sending a
* subsequent ASCONF. Note this restriction binds each side, so at any
* time two ASCONF may be in-transit on any given association (one sent
* from each endpoint).
*/
static
int
sctp_send_asconf
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
chunk
)
{
int
retval
=
0
;
/* If there is an outstanding ASCONF chunk, queue it for later
* transmission.
*/
if
(
asoc
->
addip_last_asconf
)
{
__skb_queue_tail
(
&
asoc
->
addip_chunks
,
(
struct
sk_buff
*
)
chunk
);
goto
out
;
}
/* Hold the chunk until an ASCONF_ACK is received. */
sctp_chunk_hold
(
chunk
);
retval
=
sctp_primitive_ASCONF
(
asoc
,
chunk
);
if
(
retval
)
sctp_chunk_free
(
chunk
);
else
asoc
->
addip_last_asconf
=
chunk
;
out:
return
retval
;
}
/* Add a list of addresses as bind addresses to local endpoint or
/* Add a list of addresses as bind addresses to local endpoint or
* association.
* association.
*
*
...
@@ -380,6 +421,9 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
...
@@ -380,6 +421,9 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
int
i
;
int
i
;
int
retval
=
0
;
int
retval
=
0
;
if
(
!
sctp_addip_enable
)
return
retval
;
sp
=
sctp_sk
(
sk
);
sp
=
sctp_sk
(
sk
);
ep
=
sp
->
ep
;
ep
=
sp
->
ep
;
...
@@ -389,10 +433,13 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
...
@@ -389,10 +433,13 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
list_for_each
(
pos
,
&
ep
->
asocs
)
{
list_for_each
(
pos
,
&
ep
->
asocs
)
{
asoc
=
list_entry
(
pos
,
struct
sctp_association
,
asocs
);
asoc
=
list_entry
(
pos
,
struct
sctp_association
,
asocs
);
if
(
!
sctp_state
(
asoc
,
ESTABLISHED
)
)
if
(
!
asoc
->
peer
.
asconf_capable
)
continue
;
continue
;
if
(
!
asoc
->
peer
.
asconf_capable
)
if
(
asoc
->
peer
.
addip_disabled_mask
&
SCTP_PARAM_ADD_IP
)
continue
;
if
(
!
sctp_state
(
asoc
,
ESTABLISHED
))
continue
;
continue
;
/* Check if any address in the packed array of addresses is
/* Check if any address in the packed array of addresses is
...
@@ -433,11 +480,7 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
...
@@ -433,11 +480,7 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
goto
out
;
goto
out
;
}
}
retval
=
sctp_primitive_ASCONF
(
asoc
,
chunk
);
retval
=
sctp_send_asconf
(
asoc
,
chunk
);
if
(
retval
)
{
sctp_chunk_free
(
chunk
);
goto
out
;
}
/* FIXME: After sending the add address ASCONF chunk, we
/* FIXME: After sending the add address ASCONF chunk, we
* cannot append the address to the association's binding
* cannot append the address to the association's binding
...
@@ -565,6 +608,9 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
...
@@ -565,6 +608,9 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
int
i
;
int
i
;
int
retval
=
0
;
int
retval
=
0
;
if
(
!
sctp_addip_enable
)
return
retval
;
sp
=
sctp_sk
(
sk
);
sp
=
sctp_sk
(
sk
);
ep
=
sp
->
ep
;
ep
=
sp
->
ep
;
...
@@ -574,10 +620,13 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
...
@@ -574,10 +620,13 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
list_for_each
(
pos
,
&
ep
->
asocs
)
{
list_for_each
(
pos
,
&
ep
->
asocs
)
{
asoc
=
list_entry
(
pos
,
struct
sctp_association
,
asocs
);
asoc
=
list_entry
(
pos
,
struct
sctp_association
,
asocs
);
if
(
!
sctp_state
(
asoc
,
ESTABLISHED
)
)
if
(
!
asoc
->
peer
.
asconf_capable
)
continue
;
continue
;
if
(
!
asoc
->
peer
.
asconf_capable
)
if
(
asoc
->
peer
.
addip_disabled_mask
&
SCTP_PARAM_DEL_IP
)
continue
;
if
(
!
sctp_state
(
asoc
,
ESTABLISHED
))
continue
;
continue
;
/* Check if any address in the packed array of addresses is
/* Check if any address in the packed array of addresses is
...
@@ -622,11 +671,7 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
...
@@ -622,11 +671,7 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
goto
out
;
goto
out
;
}
}
retval
=
sctp_primitive_ASCONF
(
asoc
,
chunk
);
retval
=
sctp_send_asconf
(
asoc
,
chunk
);
if
(
retval
)
{
sctp_chunk_free
(
chunk
);
goto
out
;
}
/* FIXME: After sending the delete address ASCONF chunk, we
/* FIXME: After sending the delete address ASCONF chunk, we
* cannot remove the addresses from the association's bind
* cannot remove the addresses from the association's bind
...
@@ -1920,6 +1965,9 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char *optval,
...
@@ -1920,6 +1965,9 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char *optval,
sp
=
sctp_sk
(
sk
);
sp
=
sctp_sk
(
sk
);
ep
=
sp
->
ep
;
ep
=
sp
->
ep
;
if
(
!
sctp_addip_enable
)
return
-
EPERM
;
if
(
optlen
!=
sizeof
(
struct
sctp_setpeerprim
))
if
(
optlen
!=
sizeof
(
struct
sctp_setpeerprim
))
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -1930,6 +1978,12 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char *optval,
...
@@ -1930,6 +1978,12 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char *optval,
if
(
!
asoc
)
if
(
!
asoc
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
!
asoc
->
peer
.
asconf_capable
)
return
-
EPERM
;
if
(
asoc
->
peer
.
addip_disabled_mask
&
SCTP_PARAM_SET_PRIMARY
)
return
-
EPERM
;
if
(
!
sctp_state
(
asoc
,
ESTABLISHED
))
if
(
!
sctp_state
(
asoc
,
ESTABLISHED
))
return
-
ENOTCONN
;
return
-
ENOTCONN
;
...
@@ -1942,15 +1996,11 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char *optval,
...
@@ -1942,15 +1996,11 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char *optval,
if
(
!
chunk
)
if
(
!
chunk
)
return
-
ENOMEM
;
return
-
ENOMEM
;
err
=
sctp_primitive_ASCONF
(
asoc
,
chunk
);
err
=
sctp_send_asconf
(
asoc
,
chunk
);
if
(
err
)
{
sctp_chunk_free
(
chunk
);
return
err
;
}
SCTP_DEBUG_PRINTK
(
"We set peer primary addr primitively.
\n
"
);
SCTP_DEBUG_PRINTK
(
"We set peer primary addr primitively.
\n
"
);
return
0
;
return
err
;
}
}
...
@@ -2963,8 +3013,12 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
...
@@ -2963,8 +3013,12 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
if
(
!
asoc
->
peer
.
primary_path
)
if
(
!
asoc
->
peer
.
primary_path
)
return
-
ENOTCONN
;
return
-
ENOTCONN
;
asoc
->
peer
.
primary_path
->
ipaddr
.
v4
.
sin_port
=
htons
(
asoc
->
peer
.
primary_path
->
ipaddr
.
v4
.
sin_port
);
memcpy
(
&
prim
.
ssp_addr
,
&
asoc
->
peer
.
primary_path
->
ipaddr
,
memcpy
(
&
prim
.
ssp_addr
,
&
asoc
->
peer
.
primary_path
->
ipaddr
,
sizeof
(
union
sctp_addr
));
sizeof
(
union
sctp_addr
));
asoc
->
peer
.
primary_path
->
ipaddr
.
v4
.
sin_port
=
ntohs
(
asoc
->
peer
.
primary_path
->
ipaddr
.
v4
.
sin_port
);
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sp
,
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sp
,
(
union
sctp_addr
*
)
&
prim
.
ssp_addr
);
(
union
sctp_addr
*
)
&
prim
.
ssp_addr
);
...
...
net/sctp/sysctl.c
View file @
bd23ad70
...
@@ -162,6 +162,14 @@ static ctl_table sctp_table[] = {
...
@@ -162,6 +162,14 @@ static ctl_table sctp_table[] = {
.
mode
=
0644
,
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
.
proc_handler
=
&
proc_dointvec
},
},
{
.
ctl_name
=
NET_SCTP_ADDIP_ENABLE
,
.
procname
=
"addip_enable"
,
.
data
=
&
sctp_addip_enable
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
},
{
.
ctl_name
=
0
}
{
.
ctl_name
=
0
}
};
};
...
...
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