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
cabbb4de
Commit
cabbb4de
authored
Jan 09, 2005
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-lksctp.bkbits.net/lksctp-2.5.work
into nuts.davemloft.net:/disk1/BK/net-2.6
parents
c7e670c0
a271fa8b
Changes
32
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
1030 additions
and
614 deletions
+1030
-614
include/linux/sctp.h
include/linux/sctp.h
+1
-1
include/net/sctp/command.h
include/net/sctp/command.h
+0
-13
include/net/sctp/constants.h
include/net/sctp/constants.h
+3
-5
include/net/sctp/sctp.h
include/net/sctp/sctp.h
+9
-15
include/net/sctp/sm.h
include/net/sctp/sm.h
+8
-61
include/net/sctp/structs.h
include/net/sctp/structs.h
+9
-28
include/net/sctp/tsnmap.h
include/net/sctp/tsnmap.h
+0
-16
include/net/sctp/ulpevent.h
include/net/sctp/ulpevent.h
+0
-2
include/net/sctp/ulpqueue.h
include/net/sctp/ulpqueue.h
+0
-1
net/sctp/associola.c
net/sctp/associola.c
+32
-51
net/sctp/bind_addr.c
net/sctp/bind_addr.c
+0
-17
net/sctp/chunk.c
net/sctp/chunk.c
+4
-4
net/sctp/command.c
net/sctp/command.c
+0
-23
net/sctp/debug.c
net/sctp/debug.c
+2
-18
net/sctp/endpointola.c
net/sctp/endpointola.c
+28
-28
net/sctp/input.c
net/sctp/input.c
+76
-26
net/sctp/inqueue.c
net/sctp/inqueue.c
+24
-15
net/sctp/ipv6.c
net/sctp/ipv6.c
+17
-9
net/sctp/objcnt.c
net/sctp/objcnt.c
+1
-1
net/sctp/outqueue.c
net/sctp/outqueue.c
+1
-14
net/sctp/proc.c
net/sctp/proc.c
+1
-1
net/sctp/protocol.c
net/sctp/protocol.c
+17
-17
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+104
-55
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+45
-23
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+426
-49
net/sctp/sm_statetable.c
net/sctp/sm_statetable.c
+42
-8
net/sctp/socket.c
net/sctp/socket.c
+122
-20
net/sctp/ssnmap.c
net/sctp/ssnmap.c
+5
-2
net/sctp/transport.c
net/sctp/transport.c
+38
-29
net/sctp/tsnmap.c
net/sctp/tsnmap.c
+5
-34
net/sctp/ulpevent.c
net/sctp/ulpevent.c
+9
-8
net/sctp/ulpqueue.c
net/sctp/ulpqueue.c
+1
-20
No files found.
include/linux/sctp.h
View file @
cabbb4de
...
...
@@ -364,7 +364,7 @@ typedef struct sctp_heartbeat_chunk {
*/
typedef
struct
sctp_abort_chunk
{
sctp_chunkhdr_t
uh
;
}
__attribute__
((
packed
))
sctp_abort_chunk
t
_t
;
}
__attribute__
((
packed
))
sctp_abort_chunk_t
;
/* For the graceful shutdown we must carry the tag (in common header)
...
...
include/net/sctp/command.h
View file @
cabbb4de
...
...
@@ -189,11 +189,6 @@ typedef struct {
}
sctp_cmd_seq_t
;
/* Create a new sctp_command_sequence.
* Return NULL if creating a new sequence fails.
*/
sctp_cmd_seq_t
*
sctp_new_cmd_seq
(
int
gfp
);
/* Initialize a block of memory as a command sequence.
* Return 0 if the initialization fails.
*/
...
...
@@ -207,18 +202,10 @@ int sctp_init_cmd_seq(sctp_cmd_seq_t *seq);
*/
int
sctp_add_cmd
(
sctp_cmd_seq_t
*
seq
,
sctp_verb_t
verb
,
sctp_arg_t
obj
);
/* Rewind an sctp_cmd_seq_t to iterate from the start.
* Return 0 if the rewind fails.
*/
int
sctp_rewind_sequence
(
sctp_cmd_seq_t
*
seq
);
/* Return the next command structure in an sctp_cmd_seq.
* Return NULL at the end of the sequence.
*/
sctp_cmd_t
*
sctp_next_cmd
(
sctp_cmd_seq_t
*
seq
);
/* Dispose of a command sequence. */
void
sctp_free_cmd_seq
(
sctp_cmd_seq_t
*
seq
);
#endif
/* __net_sctp_command_h__ */
include/net/sctp/constants.h
View file @
cabbb4de
...
...
@@ -105,9 +105,10 @@ typedef enum {
typedef
enum
{
SCTP_EVENT_NO_PENDING_TSN
=
0
,
SCTP_EVENT_ICMP_PROTO_UNREACH
,
}
sctp_event_other_t
;
#define SCTP_EVENT_OTHER_MAX SCTP_EVENT_
NO_PENDING_TSN
#define SCTP_EVENT_OTHER_MAX SCTP_EVENT_
ICMP_PROTO_UNREACH
#define SCTP_NUM_OTHER_TYPES (SCTP_EVENT_OTHER_MAX + 1)
/* These are primitive requests from the ULP. */
...
...
@@ -155,10 +156,6 @@ SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE, sctp_event_primitive_t, primitive)
- (unsigned long)(c->chunk_hdr)\
- sizeof(sctp_data_chunk_t)))
/* This is a table of printable names of sctp_param_t's. */
extern
const
char
*
sctp_param_tbl
[];
#define SCTP_MAX_ERROR_CAUSE SCTP_ERROR_NONEXIST_IP
#define SCTP_NUM_ERROR_CAUSE 10
...
...
@@ -179,6 +176,7 @@ typedef enum {
SCTP_IERROR_IGNORE_TSN
,
SCTP_IERROR_NO_DATA
,
SCTP_IERROR_BAD_STREAM
,
SCTP_IERROR_BAD_PORTS
,
}
sctp_ierror_t
;
...
...
include/net/sctp/sctp.h
View file @
cabbb4de
...
...
@@ -162,17 +162,9 @@ __u32 sctp_update_copy_cksum(__u8 *, __u8 *, __u16 count, __u32 cksum);
int
sctp_rcv
(
struct
sk_buff
*
skb
);
void
sctp_v4_err
(
struct
sk_buff
*
skb
,
u32
info
);
void
sctp_hash_established
(
struct
sctp_association
*
);
void
__sctp_hash_established
(
struct
sctp_association
*
);
void
sctp_unhash_established
(
struct
sctp_association
*
);
void
__sctp_unhash_established
(
struct
sctp_association
*
);
void
sctp_hash_endpoint
(
struct
sctp_endpoint
*
);
void
__sctp_hash_endpoint
(
struct
sctp_endpoint
*
);
void
sctp_unhash_endpoint
(
struct
sctp_endpoint
*
);
void
__sctp_unhash_endpoint
(
struct
sctp_endpoint
*
);
struct
sctp_association
*
__sctp_lookup_association
(
const
union
sctp_addr
*
,
const
union
sctp_addr
*
,
struct
sctp_transport
**
);
struct
sock
*
sctp_err_lookup
(
int
family
,
struct
sk_buff
*
,
struct
sctphdr
*
,
struct
sctp_endpoint
**
,
struct
sctp_association
**
,
...
...
@@ -181,6 +173,10 @@ void sctp_err_finish(struct sock *, struct sctp_endpoint *,
struct
sctp_association
*
);
void
sctp_icmp_frag_needed
(
struct
sock
*
,
struct
sctp_association
*
,
struct
sctp_transport
*
t
,
__u32
pmtu
);
void
sctp_icmp_proto_unreachable
(
struct
sock
*
sk
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
,
struct
sctp_transport
*
t
);
/*
* Section: Macros, externs, and inlines
...
...
@@ -310,8 +306,6 @@ static inline int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int
int
sctp_v6_init
(
void
);
void
sctp_v6_exit
(
void
);
void
sctp_v6_err
(
struct
sk_buff
*
skb
,
struct
inet6_skb_parm
*
opt
,
int
type
,
int
code
,
int
offset
,
__u32
info
);
#else
/* #ifdef defined(CONFIG_IPV6) */
...
...
@@ -455,7 +449,8 @@ _sctp_walk_params((pos), (chunk), WORD_ROUND(ntohs((chunk)->chunk_hdr.length)),
#define _sctp_walk_params(pos, chunk, end, member)\
for (pos.v = chunk->member;\
pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\
pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)); \
pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\
ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
pos.v += WORD_ROUND(ntohs(pos.p->length)))
#define sctp_walk_errors(err, chunk_hdr)\
...
...
@@ -465,10 +460,9 @@ _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length))
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))))
(void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) &&\
ntohs(err->length) >= sizeof(sctp_errhdr_t); \
err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
#define sctp_walk_fwdtsn(pos, chunk)\
_sctp_walk_fwdtsn((pos), (chunk), ntohs((chunk)->chunk_hdr->length) - sizeof(struct sctp_fwdtsn_chunk))
...
...
include/net/sctp/sm.h
View file @
cabbb4de
...
...
@@ -128,9 +128,9 @@ sctp_state_fn_t sctp_sf_do_9_2_shutdown;
sctp_state_fn_t
sctp_sf_do_ecn_cwr
;
sctp_state_fn_t
sctp_sf_do_ecne
;
sctp_state_fn_t
sctp_sf_ootb
;
sctp_state_fn_t
sctp_sf_shut_8_4_5
;
sctp_state_fn_t
sctp_sf_pdiscard
;
sctp_state_fn_t
sctp_sf_violation
;
sctp_state_fn_t
sctp_sf_violation_chunklen
;
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
;
...
...
@@ -138,7 +138,6 @@ sctp_state_fn_t sctp_sf_do_5_2_4_dupcook;
sctp_state_fn_t
sctp_sf_unk_chunk
;
sctp_state_fn_t
sctp_sf_do_8_5_1_E_sa
;
sctp_state_fn_t
sctp_sf_cookie_echoed_err
;
sctp_state_fn_t
sctp_sf_do_5_2_6_stale
;
sctp_state_fn_t
sctp_sf_do_asconf
;
sctp_state_fn_t
sctp_sf_do_asconf_ack
;
sctp_state_fn_t
sctp_sf_do_9_2_reshutack
;
...
...
@@ -167,6 +166,7 @@ sctp_state_fn_t sctp_sf_do_prm_asconf;
sctp_state_fn_t
sctp_sf_do_9_2_start_shutdown
;
sctp_state_fn_t
sctp_sf_do_9_2_shutdown_ack
;
sctp_state_fn_t
sctp_sf_ignore_other
;
sctp_state_fn_t
sctp_sf_cookie_wait_icmp_abort
;
/* Prototypes for timeout event state functions. */
sctp_state_fn_t
sctp_sf_do_6_3_3_rtx
;
...
...
@@ -200,19 +200,10 @@ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *,
struct
sctp_chunk
*
sctp_make_cwr
(
const
struct
sctp_association
*
,
const
__u32
lowest_tsn
,
const
struct
sctp_chunk
*
);
struct
sctp_chunk
*
sctp_make_datafrag
(
struct
sctp_association
*
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
len
,
const
__u8
*
data
,
__u8
flags
,
__u16
ssn
);
struct
sctp_chunk
*
sctp_make_datafrag_empty
(
struct
sctp_association
*
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
len
,
const
__u8
flags
,
__u16
ssn
);
struct
sctp_chunk
*
sctp_make_data
(
struct
sctp_association
*
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
len
,
const
__u8
*
data
);
struct
sctp_chunk
*
sctp_make_data_empty
(
struct
sctp_association
*
,
const
struct
sctp_sndrcvinfo
*
,
int
len
);
struct
sctp_chunk
*
sctp_make_ecne
(
const
struct
sctp_association
*
,
const
__u32
);
struct
sctp_chunk
*
sctp_make_sack
(
const
struct
sctp_association
*
);
...
...
@@ -232,6 +223,10 @@ struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *,
struct
sctp_chunk
*
sctp_make_abort_user
(
const
struct
sctp_association
*
,
const
struct
sctp_chunk
*
,
const
struct
msghdr
*
);
struct
sctp_chunk
*
sctp_make_abort_violation
(
const
struct
sctp_association
*
,
const
struct
sctp_chunk
*
,
const
__u8
*
,
const
size_t
);
struct
sctp_chunk
*
sctp_make_heartbeat
(
const
struct
sctp_association
*
,
const
struct
sctp_transport
*
,
const
void
*
payload
,
...
...
@@ -246,17 +241,12 @@ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *,
const
void
*
payload
,
size_t
paylen
);
struct
sctp_chunk
*
sctp_make_asconf
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
addr
,
int
vparam_len
);
struct
sctp_chunk
*
sctp_make_asconf_update_ip
(
struct
sctp_association
*
,
union
sctp_addr
*
,
struct
sockaddr
*
,
int
,
__u16
);
struct
sctp_chunk
*
sctp_make_asconf_set_prim
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
addr
);
struct
sctp_chunk
*
sctp_make_asconf_ack
(
const
struct
sctp_association
*
asoc
,
__u32
serial
,
int
vparam_len
);
struct
sctp_chunk
*
sctp_process_asconf
(
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
asconf
);
int
sctp_process_asconf_ack
(
struct
sctp_association
*
asoc
,
...
...
@@ -268,6 +258,8 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
void
sctp_chunk_assign_tsn
(
struct
sctp_chunk
*
);
void
sctp_chunk_assign_ssn
(
struct
sctp_chunk
*
);
void
sctp_stop_t1_and_abort
(
sctp_cmd_seq_t
*
commands
,
__u16
error
);
/* Prototypes for statetable processing. */
int
sctp_do_sm
(
sctp_event_t
event_type
,
sctp_subtype_t
subtype
,
...
...
@@ -277,71 +269,26 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
void
*
event_arg
,
int
gfp
);
int
sctp_side_effects
(
sctp_event_t
event_type
,
sctp_subtype_t
subtype
,
sctp_state_t
state
,
struct
sctp_endpoint
*
,
struct
sctp_association
*
asoc
,
void
*
event_arg
,
sctp_disposition_t
status
,
sctp_cmd_seq_t
*
commands
,
int
gfp
);
/* 2nd level prototypes */
int
sctp_cmd_interpreter
(
sctp_event_t
,
sctp_subtype_t
,
sctp_state_t
,
struct
sctp_endpoint
*
,
struct
sctp_association
*
,
void
*
event_arg
,
sctp_disposition_t
,
sctp_cmd_seq_t
*
retval
,
int
gfp
);
int
sctp_gen_sack
(
struct
sctp_association
*
,
int
force
,
sctp_cmd_seq_t
*
);
void
sctp_generate_t3_rtx_event
(
unsigned
long
peer
);
void
sctp_generate_heartbeat_event
(
unsigned
long
peer
);
sctp_sackhdr_t
*
sctp_sm_pull_sack
(
struct
sctp_chunk
*
);
struct
sctp_packet
*
sctp_abort_pkt_new
(
const
struct
sctp_endpoint
*
,
const
struct
sctp_association
*
,
struct
sctp_chunk
*
chunk
,
const
void
*
payload
,
size_t
paylen
);
struct
sctp_packet
*
sctp_ootb_pkt_new
(
const
struct
sctp_association
*
,
const
struct
sctp_chunk
*
);
void
sctp_ootb_pkt_free
(
struct
sctp_packet
*
);
struct
sctp_cookie_param
*
sctp_pack_cookie
(
const
struct
sctp_endpoint
*
,
const
struct
sctp_association
*
,
const
struct
sctp_chunk
*
,
int
*
cookie_len
,
const
__u8
*
,
int
addrs_len
);
struct
sctp_association
*
sctp_unpack_cookie
(
const
struct
sctp_endpoint
*
,
const
struct
sctp_association
*
,
struct
sctp_chunk
*
,
int
gfp
,
int
*
err
,
struct
sctp_chunk
**
err_chk_p
);
int
sctp_addip_addr_config
(
struct
sctp_association
*
,
sctp_param_t
,
struct
sockaddr_storage
*
,
int
);
void
sctp_send_stale_cookie_err
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_chunk
*
chunk
,
sctp_cmd_seq_t
*
commands
,
struct
sctp_chunk
*
err_chunk
);
int
sctp_eat_data
(
const
struct
sctp_association
*
asoc
,
struct
sctp_chunk
*
chunk
,
sctp_cmd_seq_t
*
commands
);
/* 3rd level prototypes */
__u32
sctp_generate_tag
(
const
struct
sctp_endpoint
*
);
__u32
sctp_generate_tsn
(
const
struct
sctp_endpoint
*
);
/* Extern declarations for major data structures. */
const
sctp_sm_table_entry_t
*
sctp_chunk_event_lookup
(
sctp_cid_t
,
sctp_state_t
);
extern
const
sctp_sm_table_entry_t
primitive_event_table
[
SCTP_NUM_PRIMITIVE_TYPES
][
SCTP_STATE_NUM_STATES
];
extern
const
sctp_sm_table_entry_t
other_event_table
[
SCTP_NUM_OTHER_TYPES
][
SCTP_STATE_NUM_STATES
];
extern
const
sctp_sm_table_entry_t
timeout_event_table
[
SCTP_NUM_TIMEOUT_TYPES
][
SCTP_STATE_NUM_STATES
];
extern
sctp_timer_event_t
*
sctp_timer_events
[
SCTP_NUM_TIMEOUT_TYPES
];
/* These are some handy utility macros... */
/* Get the size of a DATA chunk payload. */
static
inline
__u16
sctp_data_size
(
struct
sctp_chunk
*
chunk
)
...
...
include/net/sctp/structs.h
View file @
cabbb4de
...
...
@@ -322,10 +322,19 @@ struct sctp_cookie {
/* This holds the originating address of the INIT packet. */
union
sctp_addr
peer_addr
;
/* IG Section 2.35.3
* Include the source port of the INIT-ACK
*/
__u16
my_port
;
__u8
prsctp_capable
;
/* Padding for future use */
__u8
padding
;
__u32
adaption_ind
;
/* This is a shim for my peer's INIT packet, followed by
* a copy of the raw address list of the association.
* The length of the raw address list is saved in the
...
...
@@ -406,7 +415,6 @@ struct sctp_ssnmap {
int
malloced
;
};
struct
sctp_ssnmap
*
sctp_ssnmap_init
(
struct
sctp_ssnmap
*
,
__u16
,
__u16
);
struct
sctp_ssnmap
*
sctp_ssnmap_new
(
__u16
in
,
__u16
out
,
int
gfp
);
void
sctp_ssnmap_free
(
struct
sctp_ssnmap
*
map
);
void
sctp_ssnmap_clear
(
struct
sctp_ssnmap
*
map
);
...
...
@@ -538,12 +546,9 @@ struct sctp_datamsg {
struct
sctp_datamsg
*
sctp_datamsg_from_user
(
struct
sctp_association
*
,
struct
sctp_sndrcvinfo
*
,
struct
msghdr
*
,
int
len
);
struct
sctp_datamsg
*
sctp_datamsg_new
(
int
gfp
);
void
sctp_datamsg_put
(
struct
sctp_datamsg
*
);
void
sctp_datamsg_hold
(
struct
sctp_datamsg
*
);
void
sctp_datamsg_free
(
struct
sctp_datamsg
*
);
void
sctp_datamsg_track
(
struct
sctp_chunk
*
);
void
sctp_datamsg_assign
(
struct
sctp_datamsg
*
,
struct
sctp_chunk
*
);
void
sctp_chunk_fail
(
struct
sctp_chunk
*
,
int
error
);
int
sctp_chunk_abandoned
(
struct
sctp_chunk
*
);
...
...
@@ -651,8 +656,6 @@ void sctp_chunk_hold(struct sctp_chunk *);
void
sctp_chunk_put
(
struct
sctp_chunk
*
);
int
sctp_user_addto_chunk
(
struct
sctp_chunk
*
chunk
,
int
off
,
int
len
,
struct
iovec
*
data
);
struct
sctp_chunk
*
sctp_make_chunk
(
const
struct
sctp_association
*
,
__u8
type
,
__u8
flags
,
int
size
);
void
sctp_chunk_free
(
struct
sctp_chunk
*
);
void
*
sctp_addto_chunk
(
struct
sctp_chunk
*
,
int
len
,
const
void
*
data
);
struct
sctp_chunk
*
sctp_chunkify
(
struct
sk_buff
*
,
...
...
@@ -853,12 +856,6 @@ struct sctp_transport {
/* Error count : The current error count for this destination. */
unsigned
short
error_count
;
/* Error : Current error threshold for this destination
* Threshold : i.e. what value marks the destination down if
* : errorCount reaches this value.
*/
unsigned
short
error_threshold
;
/* This is the max_retrans value for the transport and will
* be initialized to proto.max_retrans.path. This can be changed
* using SCTP_SET_PEER_ADDR_PARAMS socket option.
...
...
@@ -922,15 +919,12 @@ struct sctp_transport {
};
struct
sctp_transport
*
sctp_transport_new
(
const
union
sctp_addr
*
,
int
);
struct
sctp_transport
*
sctp_transport_init
(
struct
sctp_transport
*
,
const
union
sctp_addr
*
,
int
);
void
sctp_transport_set_owner
(
struct
sctp_transport
*
,
struct
sctp_association
*
);
void
sctp_transport_route
(
struct
sctp_transport
*
,
union
sctp_addr
*
,
struct
sctp_opt
*
);
void
sctp_transport_pmtu
(
struct
sctp_transport
*
);
void
sctp_transport_free
(
struct
sctp_transport
*
);
void
sctp_transport_destroy
(
struct
sctp_transport
*
);
void
sctp_transport_reset_timers
(
struct
sctp_transport
*
);
void
sctp_transport_hold
(
struct
sctp_transport
*
);
void
sctp_transport_put
(
struct
sctp_transport
*
);
...
...
@@ -961,7 +955,6 @@ struct sctp_inq {
int
malloced
;
/* Is this structure kfree()able? */
};
struct
sctp_inq
*
sctp_inq_new
(
void
);
void
sctp_inq_init
(
struct
sctp_inq
*
);
void
sctp_inq_free
(
struct
sctp_inq
*
);
void
sctp_inq_push
(
struct
sctp_inq
*
,
struct
sctp_chunk
*
packet
);
...
...
@@ -1029,7 +1022,6 @@ struct sctp_outq {
char
malloced
;
};
struct
sctp_outq
*
sctp_outq_new
(
struct
sctp_association
*
);
void
sctp_outq_init
(
struct
sctp_association
*
,
struct
sctp_outq
*
);
void
sctp_outq_teardown
(
struct
sctp_outq
*
);
void
sctp_outq_free
(
struct
sctp_outq
*
);
...
...
@@ -1070,7 +1062,6 @@ struct sctp_bind_addr {
int
malloced
;
/* Are we kfree()able? */
};
struct
sctp_bind_addr
*
sctp_bind_addr_new
(
int
gfp_mask
);
void
sctp_bind_addr_init
(
struct
sctp_bind_addr
*
,
__u16
port
);
void
sctp_bind_addr_free
(
struct
sctp_bind_addr
*
);
int
sctp_bind_addr_copy
(
struct
sctp_bind_addr
*
dest
,
...
...
@@ -1220,8 +1211,6 @@ static inline struct sctp_endpoint *sctp_ep(struct sctp_ep_common *base)
/* These are function signatures for manipulating endpoints. */
struct
sctp_endpoint
*
sctp_endpoint_new
(
struct
sock
*
,
int
);
struct
sctp_endpoint
*
sctp_endpoint_init
(
struct
sctp_endpoint
*
,
struct
sock
*
,
int
gfp
);
void
sctp_endpoint_free
(
struct
sctp_endpoint
*
);
void
sctp_endpoint_put
(
struct
sctp_endpoint
*
);
void
sctp_endpoint_hold
(
struct
sctp_endpoint
*
);
...
...
@@ -1243,8 +1232,6 @@ int sctp_verify_init(const struct sctp_association *asoc, sctp_cid_t,
int
sctp_process_init
(
struct
sctp_association
*
,
sctp_cid_t
cid
,
const
union
sctp_addr
*
peer
,
sctp_init_chunk_t
*
init
,
int
gfp
);
int
sctp_process_param
(
struct
sctp_association
*
,
union
sctp_params
param
,
const
union
sctp_addr
*
from
,
int
gfp
);
__u32
sctp_generate_tag
(
const
struct
sctp_endpoint
*
);
__u32
sctp_generate_tsn
(
const
struct
sctp_endpoint
*
);
...
...
@@ -1690,10 +1677,6 @@ static inline struct sctp_association *sctp_assoc(struct sctp_ep_common *base)
struct
sctp_association
*
sctp_association_new
(
const
struct
sctp_endpoint
*
,
const
struct
sock
*
,
sctp_scope_t
scope
,
int
gfp
);
struct
sctp_association
*
sctp_association_init
(
struct
sctp_association
*
,
const
struct
sctp_endpoint
*
,
const
struct
sock
*
,
sctp_scope_t
scope
,
int
gfp
);
void
sctp_association_free
(
struct
sctp_association
*
);
void
sctp_association_put
(
struct
sctp_association
*
);
void
sctp_association_hold
(
struct
sctp_association
*
);
...
...
@@ -1722,7 +1705,6 @@ void sctp_assoc_update(struct sctp_association *old,
struct
sctp_association
*
new
);
__u32
sctp_association_get_next_tsn
(
struct
sctp_association
*
);
__u32
sctp_association_get_tsn_block
(
struct
sctp_association
*
,
int
);
void
sctp_assoc_sync_pmtu
(
struct
sctp_association
*
);
void
sctp_assoc_rwnd_increase
(
struct
sctp_association
*
,
unsigned
);
...
...
@@ -1736,7 +1718,6 @@ int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
int
sctp_cmp_addr_exact
(
const
union
sctp_addr
*
ss1
,
const
union
sctp_addr
*
ss2
);
struct
sctp_chunk
*
sctp_get_ecne_prepend
(
struct
sctp_association
*
asoc
);
struct
sctp_chunk
*
sctp_get_no_prepend
(
struct
sctp_association
*
asoc
);
/* A convenience structure to parse out SCTP specific CMSGs. */
typedef
struct
sctp_cmsgs
{
...
...
include/net/sctp/tsnmap.h
View file @
cabbb4de
...
...
@@ -120,12 +120,6 @@ struct sctp_tsnmap_iter {
__u32
start
;
};
/* Create a new tsnmap. */
struct
sctp_tsnmap
*
sctp_tsnmap_new
(
__u16
len
,
__u32
init_tsn
,
int
gfp
);
/* Dispose of a tsnmap. */
void
sctp_tsnmap_free
(
struct
sctp_tsnmap
*
);
/* This macro assists in creation of external storage for variable length
* internal buffers. We double allocate so the overflow map works.
*/
...
...
@@ -210,14 +204,4 @@ void sctp_tsnmap_renege(struct sctp_tsnmap *, __u32 tsn);
/* Is there a gap in the TSN map? */
int
sctp_tsnmap_has_gap
(
const
struct
sctp_tsnmap
*
);
/* Initialize a gap ack block interator from user-provided memory. */
void
sctp_tsnmap_iter_init
(
const
struct
sctp_tsnmap
*
,
struct
sctp_tsnmap_iter
*
);
/* Get the next gap ack blocks. We return 0 if there are no more
* gap ack blocks.
*/
int
sctp_tsnmap_next_gap_ack
(
const
struct
sctp_tsnmap
*
,
struct
sctp_tsnmap_iter
*
,
__u16
*
start
,
__u16
*
end
);
#endif
/* __sctp_tsnmap_h__ */
include/net/sctp/ulpevent.h
View file @
cabbb4de
...
...
@@ -77,8 +77,6 @@ static inline struct sctp_ulpevent *sctp_skb2event(struct sk_buff *skb)
return
(
struct
sctp_ulpevent
*
)
skb
->
cb
;
}
struct
sctp_ulpevent
*
sctp_ulpevent_new
(
int
size
,
int
flags
,
int
gfp
);
void
sctp_ulpevent_init
(
struct
sctp_ulpevent
*
,
int
flags
);
void
sctp_ulpevent_free
(
struct
sctp_ulpevent
*
);
int
sctp_ulpevent_is_notification
(
const
struct
sctp_ulpevent
*
);
void
sctp_queue_purge_ulpevents
(
struct
sk_buff_head
*
list
);
...
...
include/net/sctp/ulpqueue.h
View file @
cabbb4de
...
...
@@ -57,7 +57,6 @@ struct sctp_ulpq {
};
/* Prototypes. */
struct
sctp_ulpq
*
sctp_ulpq_new
(
struct
sctp_association
*
asoc
,
int
gfp
);
struct
sctp_ulpq
*
sctp_ulpq_init
(
struct
sctp_ulpq
*
,
struct
sctp_association
*
);
void
sctp_ulpq_free
(
struct
sctp_ulpq
*
);
...
...
net/sctp/associola.c
View file @
cabbb4de
...
...
@@ -66,33 +66,8 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc);
/* 1st Level Abstractions. */
/* Allocate and initialize a new association */
struct
sctp_association
*
sctp_association_new
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sock
*
sk
,
sctp_scope_t
scope
,
int
gfp
)
{
struct
sctp_association
*
asoc
;
asoc
=
t_new
(
struct
sctp_association
,
gfp
);
if
(
!
asoc
)
goto
fail
;
if
(
!
sctp_association_init
(
asoc
,
ep
,
sk
,
scope
,
gfp
))
goto
fail_init
;
asoc
->
base
.
malloced
=
1
;
SCTP_DBG_OBJCNT_INC
(
assoc
);
return
asoc
;
fail_init:
kfree
(
asoc
);
fail:
return
NULL
;
}
/* Initialize a new association from provided memory. */
struct
sctp_association
*
sctp_association_init
(
struct
sctp_association
*
asoc
,
st
atic
st
ruct
sctp_association
*
sctp_association_init
(
struct
sctp_association
*
asoc
,
const
struct
sctp_endpoint
*
ep
,
const
struct
sock
*
sk
,
sctp_scope_t
scope
,
...
...
@@ -204,6 +179,7 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
asoc
->
c
.
peer_vtag
=
0
;
asoc
->
c
.
my_ttag
=
0
;
asoc
->
c
.
peer_ttag
=
0
;
asoc
->
c
.
my_port
=
ep
->
base
.
bind_addr
.
port
;
asoc
->
c
.
initial_tsn
=
sctp_generate_tsn
(
ep
);
...
...
@@ -296,6 +272,31 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
return
NULL
;
}
/* Allocate and initialize a new association */
struct
sctp_association
*
sctp_association_new
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sock
*
sk
,
sctp_scope_t
scope
,
int
gfp
)
{
struct
sctp_association
*
asoc
;
asoc
=
t_new
(
struct
sctp_association
,
gfp
);
if
(
!
asoc
)
goto
fail
;
if
(
!
sctp_association_init
(
asoc
,
ep
,
sk
,
scope
,
gfp
))
goto
fail_init
;
asoc
->
base
.
malloced
=
1
;
SCTP_DBG_OBJCNT_INC
(
assoc
);
return
asoc
;
fail_init:
kfree
(
asoc
);
fail:
return
NULL
;
}
/* Free this association if possible. There may still be users, so
* the actual deallocation may be delayed.
*/
...
...
@@ -500,7 +501,6 @@ 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
;
/* By default, enable heartbeat for peer address. */
peer
->
hb_allowed
=
1
;
...
...
@@ -511,7 +511,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
peer
->
hb_interval
=
msecs_to_jiffies
(
sp
->
paddrparam
.
spp_hbinterval
);
/* Set the path max_retrans. */
peer
->
max_retrans
=
asoc
->
max_retrans
;
peer
->
max_retrans
=
sp
->
paddrparam
.
spp_pathmaxrxt
;
/* Set the transport's RTO.initial value */
peer
->
rto
=
asoc
->
rto_initial
;
...
...
@@ -714,18 +714,6 @@ __u32 sctp_association_get_next_tsn(struct sctp_association *asoc)
return
retval
;
}
/* Allocate 'num' TSNs by incrementing the association's TSN by num. */
__u32
sctp_association_get_tsn_block
(
struct
sctp_association
*
asoc
,
int
num
)
{
__u32
retval
=
asoc
->
next_tsn
;
asoc
->
next_tsn
+=
num
;
asoc
->
unack_data
+=
num
;
return
retval
;
}
/* Compare two addresses to see if they match. Wildcard addresses
* only match themselves.
*/
...
...
@@ -760,14 +748,6 @@ struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc)
return
chunk
;
}
/* Use this function for the packet prepend callback when no ECNE
* packet is desired (e.g. some packets don't like to be bundled).
*/
struct
sctp_chunk
*
sctp_get_no_prepend
(
struct
sctp_association
*
asoc
)
{
return
NULL
;
}
/*
* Find which transport this TSN was sent on.
*/
...
...
@@ -861,7 +841,8 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
struct
sctp_chunk
*
chunk
;
struct
sock
*
sk
;
struct
sctp_inq
*
inqueue
;
int
state
,
subtype
;
int
state
;
sctp_subtype_t
subtype
;
int
error
=
0
;
/* The association should be held so we should be safe. */
...
...
@@ -872,7 +853,7 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
sctp_association_hold
(
asoc
);
while
(
NULL
!=
(
chunk
=
sctp_inq_pop
(
inqueue
)))
{
state
=
asoc
->
state
;
subtype
=
chunk
->
chunk_hdr
->
type
;
subtype
=
SCTP_ST_CHUNK
(
chunk
->
chunk_hdr
->
type
)
;
/* Remember where the last DATA chunk came from so we
* know where to send the SACK.
...
...
@@ -886,7 +867,7 @@ static void sctp_assoc_bh_rcv(struct sctp_association *asoc)
chunk
->
transport
->
last_time_heard
=
jiffies
;
/* Run through the state machine. */
error
=
sctp_do_sm
(
SCTP_EVENT_T_CHUNK
,
SCTP_ST_CHUNK
(
subtype
)
,
error
=
sctp_do_sm
(
SCTP_EVENT_T_CHUNK
,
subtype
,
state
,
ep
,
asoc
,
chunk
,
GFP_ATOMIC
);
/* Check to see if the association is freed in response to
...
...
net/sctp/bind_addr.c
View file @
cabbb4de
...
...
@@ -104,23 +104,6 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
return
error
;
}
/* Create a new SCTP_bind_addr from nothing. */
struct
sctp_bind_addr
*
sctp_bind_addr_new
(
int
gfp
)
{
struct
sctp_bind_addr
*
retval
;
retval
=
t_new
(
struct
sctp_bind_addr
,
gfp
);
if
(
!
retval
)
goto
nomem
;
sctp_bind_addr_init
(
retval
,
0
);
retval
->
malloced
=
1
;
SCTP_DBG_OBJCNT_INC
(
bind_addr
);
nomem:
return
retval
;
}
/* Initialize the SCTP_bind_addr structure for either an endpoint or
* an association.
*/
...
...
net/sctp/chunk.c
View file @
cabbb4de
...
...
@@ -51,7 +51,7 @@
*/
/* Initialize datamsg from memory. */
void
sctp_datamsg_init
(
struct
sctp_datamsg
*
msg
)
static
void
sctp_datamsg_init
(
struct
sctp_datamsg
*
msg
)
{
atomic_set
(
&
msg
->
refcnt
,
1
);
msg
->
send_failed
=
0
;
...
...
@@ -62,7 +62,7 @@ void sctp_datamsg_init(struct sctp_datamsg *msg)
}
/* Allocate and initialize datamsg. */
struct
sctp_datamsg
*
sctp_datamsg_new
(
int
gfp
)
SCTP_STATIC
struct
sctp_datamsg
*
sctp_datamsg_new
(
int
gfp
)
{
struct
sctp_datamsg
*
msg
;
msg
=
kmalloc
(
sizeof
(
struct
sctp_datamsg
),
gfp
);
...
...
@@ -124,7 +124,7 @@ static void sctp_datamsg_destroy(struct sctp_datamsg *msg)
}
/* Hold a reference. */
void
sctp_datamsg_hold
(
struct
sctp_datamsg
*
msg
)
static
void
sctp_datamsg_hold
(
struct
sctp_datamsg
*
msg
)
{
atomic_inc
(
&
msg
->
refcnt
);
}
...
...
@@ -151,7 +151,7 @@ void sctp_datamsg_track(struct sctp_chunk *chunk)
}
/* Assign a chunk to this datamsg. */
void
sctp_datamsg_assign
(
struct
sctp_datamsg
*
msg
,
struct
sctp_chunk
*
chunk
)
static
void
sctp_datamsg_assign
(
struct
sctp_datamsg
*
msg
,
struct
sctp_chunk
*
chunk
)
{
sctp_datamsg_hold
(
msg
);
chunk
->
msg
=
msg
;
...
...
net/sctp/command.c
View file @
cabbb4de
...
...
@@ -42,17 +42,6 @@
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
/* Create a new sctp_command_sequence. */
sctp_cmd_seq_t
*
sctp_new_cmd_seq
(
int
gfp
)
{
sctp_cmd_seq_t
*
retval
=
t_new
(
sctp_cmd_seq_t
,
gfp
);
if
(
retval
)
sctp_init_cmd_seq
(
retval
);
return
retval
;
}
/* Initialize a block of memory as a command sequence. */
int
sctp_init_cmd_seq
(
sctp_cmd_seq_t
*
seq
)
{
...
...
@@ -77,13 +66,6 @@ int sctp_add_cmd(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj)
return
0
;
}
/* Rewind an sctp_cmd_seq_t to iterate from the start. */
int
sctp_rewind_sequence
(
sctp_cmd_seq_t
*
seq
)
{
seq
->
next_cmd
=
0
;
return
1
;
/* We always succeed. */
}
/* Return the next command structure in a sctp_cmd_seq.
* Returns NULL at the end of the sequence.
*/
...
...
@@ -97,8 +79,3 @@ sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq)
return
retval
;
}
/* Dispose of a command sequence. */
void
sctp_free_cmd_seq
(
sctp_cmd_seq_t
*
seq
)
{
kfree
(
seq
);
}
net/sctp/debug.c
View file @
cabbb4de
...
...
@@ -98,23 +98,6 @@ const char *sctp_cname(const sctp_subtype_t cid)
return
"unknown chunk"
;
}
/* These are printable form of variable-length parameters. */
const
char
*
sctp_param_tbl
[
SCTP_PARAM_ECN_CAPABLE
+
1
]
=
{
""
,
"PARAM_HEARTBEAT_INFO"
,
""
,
""
,
""
,
"PARAM_IPV4_ADDRESS"
,
"PARAM_IPV6_ADDRESS"
,
"PARAM_STATE_COOKIE"
,
"PARAM_UNRECOGNIZED_PARAMETERS"
,
"PARAM_COOKIE_PRESERVATIVE"
,
""
,
"PARAM_HOST_NAME_ADDRESS"
,
"PARAM_SUPPORTED_ADDRESS_TYPES"
,
};
/* These are printable forms of the states. */
const
char
*
sctp_state_tbl
[
SCTP_STATE_NUM_STATES
]
=
{
"STATE_EMPTY"
,
...
...
@@ -171,6 +154,7 @@ const char *sctp_pname(const sctp_subtype_t id)
static
const
char
*
sctp_other_tbl
[]
=
{
"NO_PENDING_TSN"
,
"ICMP_PROTO_UNREACH"
,
};
/* Lookup "other" debug name. */
...
...
@@ -178,7 +162,7 @@ const char *sctp_oname(const sctp_subtype_t id)
{
if
(
id
.
other
<
0
)
return
"illegal 'other' event"
;
if
(
id
.
other
<
SCTP_EVENT_OTHER_MAX
)
if
(
id
.
other
<
=
SCTP_EVENT_OTHER_MAX
)
return
sctp_other_tbl
[
id
.
other
];
return
"unknown 'other' event"
;
}
...
...
net/sctp/endpointola.c
View file @
cabbb4de
...
...
@@ -63,34 +63,11 @@
/* Forward declarations for internal helpers. */
static
void
sctp_endpoint_bh_rcv
(
struct
sctp_endpoint
*
ep
);
/* Create a sctp_endpoint with all that boring stuff initialized.
* Returns NULL if there isn't enough memory.
*/
struct
sctp_endpoint
*
sctp_endpoint_new
(
struct
sock
*
sk
,
int
gfp
)
{
struct
sctp_endpoint
*
ep
;
/* Build a local endpoint. */
ep
=
t_new
(
struct
sctp_endpoint
,
gfp
);
if
(
!
ep
)
goto
fail
;
if
(
!
sctp_endpoint_init
(
ep
,
sk
,
gfp
))
goto
fail_init
;
ep
->
base
.
malloced
=
1
;
SCTP_DBG_OBJCNT_INC
(
ep
);
return
ep
;
fail_init:
kfree
(
ep
);
fail:
return
NULL
;
}
/*
* Initialize the base fields of the endpoint structure.
*/
struct
sctp_endpoint
*
sctp_endpoint_init
(
struct
sctp_endpoint
*
ep
,
struct
sock
*
sk
,
int
gfp
)
st
atic
st
ruct
sctp_endpoint
*
sctp_endpoint_init
(
struct
sctp_endpoint
*
ep
,
struct
sock
*
sk
,
int
gfp
)
{
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
memset
(
ep
,
0
,
sizeof
(
struct
sctp_endpoint
));
...
...
@@ -160,6 +137,29 @@ struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
return
ep
;
}
/* Create a sctp_endpoint with all that boring stuff initialized.
* Returns NULL if there isn't enough memory.
*/
struct
sctp_endpoint
*
sctp_endpoint_new
(
struct
sock
*
sk
,
int
gfp
)
{
struct
sctp_endpoint
*
ep
;
/* Build a local endpoint. */
ep
=
t_new
(
struct
sctp_endpoint
,
gfp
);
if
(
!
ep
)
goto
fail
;
if
(
!
sctp_endpoint_init
(
ep
,
sk
,
gfp
))
goto
fail_init
;
ep
->
base
.
malloced
=
1
;
SCTP_DBG_OBJCNT_INC
(
ep
);
return
ep
;
fail_init:
kfree
(
ep
);
fail:
return
NULL
;
}
/* Add an association to an endpoint. */
void
sctp_endpoint_add_asoc
(
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
)
...
...
@@ -184,7 +184,7 @@ void sctp_endpoint_free(struct sctp_endpoint *ep)
}
/* Final destructor for endpoint. */
void
sctp_endpoint_destroy
(
struct
sctp_endpoint
*
ep
)
static
void
sctp_endpoint_destroy
(
struct
sctp_endpoint
*
ep
)
{
SCTP_ASSERT
(
ep
->
base
.
dead
,
"Endpoint is not dead"
,
return
);
...
...
@@ -257,7 +257,7 @@ struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep,
* We do a linear search of the associations for this endpoint.
* We return the matching transport address too.
*/
struct
sctp_association
*
__sctp_endpoint_lookup_assoc
(
st
atic
st
ruct
sctp_association
*
__sctp_endpoint_lookup_assoc
(
const
struct
sctp_endpoint
*
ep
,
const
union
sctp_addr
*
paddr
,
struct
sctp_transport
**
transport
)
...
...
@@ -345,7 +345,7 @@ static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep)
sk
=
ep
->
base
.
sk
;
while
(
NULL
!=
(
chunk
=
sctp_inq_pop
(
inqueue
)))
{
subtype
.
chunk
=
chunk
->
chunk_hdr
->
type
;
subtype
=
SCTP_ST_CHUNK
(
chunk
->
chunk_hdr
->
type
)
;
/* We might have grown an association since last we
* looked, so try again.
...
...
net/sctp/input.c
View file @
cabbb4de
...
...
@@ -63,11 +63,15 @@
/* Forward declarations for internal helpers. */
static
int
sctp_rcv_ootb
(
struct
sk_buff
*
);
struct
sctp_association
*
__sctp_rcv_lookup
(
struct
sk_buff
*
skb
,
st
atic
st
ruct
sctp_association
*
__sctp_rcv_lookup
(
struct
sk_buff
*
skb
,
const
union
sctp_addr
*
laddr
,
const
union
sctp_addr
*
paddr
,
struct
sctp_transport
**
transportp
);
struct
sctp_endpoint
*
__sctp_rcv_lookup_endpoint
(
const
union
sctp_addr
*
laddr
);
static
struct
sctp_endpoint
*
__sctp_rcv_lookup_endpoint
(
const
union
sctp_addr
*
laddr
);
static
struct
sctp_association
*
__sctp_lookup_association
(
const
union
sctp_addr
*
local
,
const
union
sctp_addr
*
peer
,
struct
sctp_transport
**
pt
);
/* Calculate the SCTP checksum of an SCTP packet. */
...
...
@@ -130,6 +134,10 @@ int sctp_rcv(struct sk_buff *skb)
skb_pull
(
skb
,
sizeof
(
struct
sctphdr
));
/* Make sure we at least have chunk headers worth of data left. */
if
(
skb
->
len
<
sizeof
(
struct
sctp_chunkhdr
))
goto
discard_it
;
family
=
ipver2af
(
skb
->
nh
.
iph
->
version
);
af
=
sctp_get_af_specific
(
family
);
if
(
unlikely
(
!
af
))
...
...
@@ -284,6 +292,31 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
}
}
/*
* SCTP Implementer's Guide, 2.37 ICMP handling procedures
*
* ICMP8) If the ICMP code is a "Unrecognized next header type encountered"
* or a "Protocol Unreachable" treat this message as an abort
* with the T bit set.
*
* This function sends an event to the state machine, which will abort the
* association.
*
*/
void
sctp_icmp_proto_unreachable
(
struct
sock
*
sk
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
,
struct
sctp_transport
*
t
)
{
SCTP_DEBUG_PRINTK
(
"%s
\n
"
,
__FUNCTION__
);
sctp_do_sm
(
SCTP_EVENT_T_OTHER
,
SCTP_ST_OTHER
(
SCTP_EVENT_ICMP_PROTO_UNREACH
),
asoc
->
state
,
asoc
->
ep
,
asoc
,
NULL
,
GFP_ATOMIC
);
}
/* Common lookup code for icmp/icmpv6 error handler. */
struct
sock
*
sctp_err_lookup
(
int
family
,
struct
sk_buff
*
skb
,
struct
sctphdr
*
sctphdr
,
...
...
@@ -326,11 +359,12 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
}
if
(
asoc
)
{
sk
=
asoc
->
base
.
sk
;
if
(
ntohl
(
sctphdr
->
vtag
)
!=
asoc
->
c
.
peer_vtag
)
{
ICMP_INC_STATS_BH
(
ICMP_MIB_INERRORS
);
goto
out
;
}
sk
=
asoc
->
base
.
sk
;
}
else
sk
=
ep
->
base
.
sk
;
...
...
@@ -432,7 +466,13 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
sctp_icmp_frag_needed
(
sk
,
asoc
,
transport
,
info
);
goto
out_unlock
;
}
else
{
if
(
ICMP_PROT_UNREACH
==
code
)
{
sctp_icmp_proto_unreachable
(
sk
,
ep
,
asoc
,
transport
);
goto
out_unlock
;
}
}
err
=
icmp_err_convert
[
code
].
errno
;
break
;
case
ICMP_TIME_EXCEEDED
:
...
...
@@ -479,10 +519,10 @@ int sctp_rcv_ootb(struct sk_buff *skb)
sctp_errhdr_t
*
err
;
ch
=
(
sctp_chunkhdr_t
*
)
skb
->
data
;
ch_end
=
((
__u8
*
)
ch
)
+
WORD_ROUND
(
ntohs
(
ch
->
length
));
/* Scan through all the chunks in the packet. */
do
{
ch_end
=
((
__u8
*
)
ch
)
+
WORD_ROUND
(
ntohs
(
ch
->
length
));
while
(
ch_end
>
(
__u8
*
)
ch
&&
ch_end
<
skb
->
tail
)
{
/* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the
* receiver MUST silently discard the OOTB packet and take no
...
...
@@ -513,7 +553,8 @@ int sctp_rcv_ootb(struct sk_buff *skb)
}
ch
=
(
sctp_chunkhdr_t
*
)
ch_end
;
}
while
(
ch_end
<
skb
->
tail
);
ch_end
=
((
__u8
*
)
ch
)
+
WORD_ROUND
(
ntohs
(
ch
->
length
));
}
return
0
;
...
...
@@ -522,7 +563,7 @@ int sctp_rcv_ootb(struct sk_buff *skb)
}
/* Insert endpoint into the hash table. */
void
__sctp_hash_endpoint
(
struct
sctp_endpoint
*
ep
)
static
void
__sctp_hash_endpoint
(
struct
sctp_endpoint
*
ep
)
{
struct
sctp_ep_common
**
epp
;
struct
sctp_ep_common
*
epb
;
...
...
@@ -552,7 +593,7 @@ void sctp_hash_endpoint(struct sctp_endpoint *ep)
}
/* Remove endpoint from the hash table. */
void
__sctp_unhash_endpoint
(
struct
sctp_endpoint
*
ep
)
static
void
__sctp_unhash_endpoint
(
struct
sctp_endpoint
*
ep
)
{
struct
sctp_hashbucket
*
head
;
struct
sctp_ep_common
*
epb
;
...
...
@@ -584,7 +625,7 @@ void sctp_unhash_endpoint(struct sctp_endpoint *ep)
}
/* Look up an endpoint. */
struct
sctp_endpoint
*
__sctp_rcv_lookup_endpoint
(
const
union
sctp_addr
*
laddr
)
st
atic
st
ruct
sctp_endpoint
*
__sctp_rcv_lookup_endpoint
(
const
union
sctp_addr
*
laddr
)
{
struct
sctp_hashbucket
*
head
;
struct
sctp_ep_common
*
epb
;
...
...
@@ -610,16 +651,8 @@ struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr)
return
ep
;
}
/* Add an association to the hash. Local BH-safe. */
void
sctp_hash_established
(
struct
sctp_association
*
asoc
)
{
sctp_local_bh_disable
();
__sctp_hash_established
(
asoc
);
sctp_local_bh_enable
();
}
/* Insert association into the hash table. */
void
__sctp_hash_established
(
struct
sctp_association
*
asoc
)
static
void
__sctp_hash_established
(
struct
sctp_association
*
asoc
)
{
struct
sctp_ep_common
**
epp
;
struct
sctp_ep_common
*
epb
;
...
...
@@ -642,16 +675,16 @@ void __sctp_hash_established(struct sctp_association *asoc)
sctp_write_unlock
(
&
head
->
lock
);
}
/*
Remove association from the hash table.
Local BH-safe. */
void
sctp_
un
hash_established
(
struct
sctp_association
*
asoc
)
/*
Add an association to the hash.
Local BH-safe. */
void
sctp_hash_established
(
struct
sctp_association
*
asoc
)
{
sctp_local_bh_disable
();
__sctp_
un
hash_established
(
asoc
);
__sctp_hash_established
(
asoc
);
sctp_local_bh_enable
();
}
/* Remove association from the hash table. */
void
__sctp_unhash_established
(
struct
sctp_association
*
asoc
)
static
void
__sctp_unhash_established
(
struct
sctp_association
*
asoc
)
{
struct
sctp_hashbucket
*
head
;
struct
sctp_ep_common
*
epb
;
...
...
@@ -675,8 +708,16 @@ void __sctp_unhash_established(struct sctp_association *asoc)
sctp_write_unlock
(
&
head
->
lock
);
}
/* Remove association from the hash table. Local BH-safe. */
void
sctp_unhash_established
(
struct
sctp_association
*
asoc
)
{
sctp_local_bh_disable
();
__sctp_unhash_established
(
asoc
);
sctp_local_bh_enable
();
}
/* Look up an association. */
struct
sctp_association
*
__sctp_lookup_association
(
st
atic
st
ruct
sctp_association
*
__sctp_lookup_association
(
const
union
sctp_addr
*
local
,
const
union
sctp_addr
*
peer
,
struct
sctp_transport
**
pt
)
...
...
@@ -713,8 +754,9 @@ struct sctp_association *__sctp_lookup_association(
}
/* Look up an association. BH-safe. */
SCTP_STATIC
struct
sctp_association
*
sctp_lookup_association
(
const
union
sctp_addr
*
laddr
,
const
union
sctp_addr
*
paddr
,
const
union
sctp_addr
*
paddr
,
struct
sctp_transport
**
transportp
)
{
struct
sctp_association
*
asoc
;
...
...
@@ -784,6 +826,14 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
return
NULL
;
}
/* The code below will attempt to walk the chunk and extract
* parameter information. Before we do that, we need to verify
* that the chunk length doesn't cause overflow. Otherwise, we'll
* walk off the end.
*/
if
(
WORD_ROUND
(
ntohs
(
ch
->
length
))
>
skb
->
len
)
return
NULL
;
/*
* This code will NOT touch anything inside the chunk--it is
* strictly READ-ONLY.
...
...
@@ -821,7 +871,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
}
/* Lookup an association for an inbound skb. */
struct
sctp_association
*
__sctp_rcv_lookup
(
struct
sk_buff
*
skb
,
st
atic
st
ruct
sctp_association
*
__sctp_rcv_lookup
(
struct
sk_buff
*
skb
,
const
union
sctp_addr
*
paddr
,
const
union
sctp_addr
*
laddr
,
struct
sctp_transport
**
transportp
)
...
...
net/sctp/inqueue.c
View file @
cabbb4de
...
...
@@ -59,19 +59,6 @@ void sctp_inq_init(struct sctp_inq *queue)
queue
->
malloced
=
0
;
}
/* Create an initialized sctp_inq. */
struct
sctp_inq
*
sctp_inq_new
(
void
)
{
struct
sctp_inq
*
retval
;
retval
=
t_new
(
struct
sctp_inq
,
GFP_ATOMIC
);
if
(
retval
)
{
sctp_inq_init
(
retval
);
retval
->
malloced
=
1
;
}
return
retval
;
}
/* Release the memory associated with an SCTP inqueue. */
void
sctp_inq_free
(
struct
sctp_inq
*
queue
)
{
...
...
@@ -157,14 +144,36 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
}
chunk
->
chunk_hdr
=
ch
;
chunk
->
chunk_end
=
((
__u8
*
)
ch
)
+
WORD_ROUND
(
ntohs
(
ch
->
length
));
chunk
->
chunk_end
=
((
__u8
*
)
ch
)
+
WORD_ROUND
(
ntohs
(
ch
->
length
));
/* In the unlikely case of an IP reassembly, the skb could be
* non-linear. If so, update chunk_end so that it doesn't go past
* the skb->tail.
*/
if
(
unlikely
(
skb_is_nonlinear
(
chunk
->
skb
)))
{
if
(
chunk
->
chunk_end
>
chunk
->
skb
->
tail
)
chunk
->
chunk_end
=
chunk
->
skb
->
tail
;
}
skb_pull
(
chunk
->
skb
,
sizeof
(
sctp_chunkhdr_t
));
chunk
->
subh
.
v
=
NULL
;
/* Subheader is no longer valid. */
if
(
chunk
->
chunk_end
<
chunk
->
skb
->
tail
)
{
/* This is not a singleton */
chunk
->
singleton
=
0
;
}
else
if
(
chunk
->
chunk_end
>
chunk
->
skb
->
tail
)
{
/* RFC 2960, Section 6.10 Bundling
*
* Partial chunks MUST NOT be placed in an SCTP packet.
* If the receiver detects a partial chunk, it MUST drop
* the chunk.
*
* Since the end of the chunk is past the end of our buffer
* (which contains the whole packet, we can freely discard
* the whole packet.
*/
sctp_chunk_free
(
chunk
);
chunk
=
queue
->
in_progress
=
NULL
;
return
NULL
;
}
else
{
/* We are at the end of the packet, so mark the chunk
* in case we need to send a SACK.
...
...
net/sctp/ipv6.c
View file @
cabbb4de
...
...
@@ -84,8 +84,8 @@ static struct notifier_block sctp_inet6addr_notifier = {
};
/* ICMP error handler. */
void
sctp_v6_err
(
struct
sk_buff
*
skb
,
struct
inet6_skb_parm
*
opt
,
int
type
,
int
code
,
int
offset
,
__u32
info
)
SCTP_STATIC
void
sctp_v6_err
(
struct
sk_buff
*
skb
,
struct
inet6_skb_parm
*
opt
,
int
type
,
int
code
,
int
offset
,
__u32
info
)
{
struct
inet6_dev
*
idev
;
struct
ipv6hdr
*
iph
=
(
struct
ipv6hdr
*
)
skb
->
data
;
...
...
@@ -122,6 +122,12 @@ void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
case
ICMPV6_PKT_TOOBIG
:
sctp_icmp_frag_needed
(
sk
,
asoc
,
transport
,
ntohl
(
info
));
goto
out_unlock
;
case
ICMPV6_PARAMPROB
:
if
(
ICMPV6_UNK_NEXTHDR
==
code
)
{
sctp_icmp_proto_unreachable
(
sk
,
ep
,
asoc
,
transport
);
goto
out_unlock
;
}
break
;
default:
break
;
}
...
...
@@ -188,9 +194,9 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
/* Returns the dst cache entry for the given source and destination ip
* addresses.
*/
struct
dst_entry
*
sctp_v6_get_dst
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
st
atic
st
ruct
dst_entry
*
sctp_v6_get_dst
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
{
struct
dst_entry
*
dst
;
struct
flowi
fl
;
...
...
@@ -251,8 +257,10 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
/* Fills in the source address(saddr) based on the destination address(daddr)
* and asoc's bind address list.
*/
void
sctp_v6_get_saddr
(
struct
sctp_association
*
asoc
,
struct
dst_entry
*
dst
,
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
static
void
sctp_v6_get_saddr
(
struct
sctp_association
*
asoc
,
struct
dst_entry
*
dst
,
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
{
struct
sctp_bind_addr
*
bp
;
rwlock_t
*
addr_lock
;
...
...
@@ -577,8 +585,8 @@ static sctp_scope_t sctp_v6_scope(union sctp_addr *addr)
}
/* Create and initialize a new sk for the socket to be returned by accept(). */
struct
sock
*
sctp_v6_create_accept_sk
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
)
st
atic
st
ruct
sock
*
sctp_v6_create_accept_sk
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
)
{
struct
inet_sock
*
inet
=
inet_sk
(
sk
);
struct
sock
*
newsk
;
...
...
net/sctp/objcnt.c
View file @
cabbb4de
...
...
@@ -62,7 +62,7 @@ SCTP_DBG_OBJCNT(datamsg);
/* An array to make it easy to pretty print the debug information
* to the proc fs.
*/
sctp_dbg_objcnt_entry_t
sctp_dbg_objcnt
[]
=
{
s
tatic
s
ctp_dbg_objcnt_entry_t
sctp_dbg_objcnt
[]
=
{
SCTP_DBG_OBJCNT_ENTRY
(
sock
),
SCTP_DBG_OBJCNT_ENTRY
(
ep
),
SCTP_DBG_OBJCNT_ENTRY
(
assoc
),
...
...
net/sctp/outqueue.c
View file @
cabbb4de
...
...
@@ -190,19 +190,6 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary,
return
0
;
}
/* Generate a new outqueue. */
struct
sctp_outq
*
sctp_outq_new
(
struct
sctp_association
*
asoc
)
{
struct
sctp_outq
*
q
;
q
=
t_new
(
struct
sctp_outq
,
GFP_KERNEL
);
if
(
q
)
{
sctp_outq_init
(
asoc
,
q
);
q
->
malloced
=
1
;
}
return
q
;
}
/* Initialize an existing sctp_outq. This does the boring stuff.
* You still need to define handlers if you really want to DO
* something with this structure...
...
...
@@ -362,7 +349,7 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk)
/* Insert a chunk into the sorted list based on the TSNs. The retransmit list
* and the abandoned list are in ascending order.
*/
void
sctp_insert_list
(
struct
list_head
*
head
,
struct
list_head
*
new
)
static
void
sctp_insert_list
(
struct
list_head
*
head
,
struct
list_head
*
new
)
{
struct
list_head
*
pos
;
struct
sctp_chunk
*
nchunk
,
*
lchunk
;
...
...
net/sctp/proc.c
View file @
cabbb4de
...
...
@@ -39,7 +39,7 @@
#include <linux/init.h>
#include <net/sctp/sctp.h>
struct
snmp_mib
sctp_snmp_list
[]
=
{
st
atic
st
ruct
snmp_mib
sctp_snmp_list
[]
=
{
SNMP_MIB_ITEM
(
"SctpCurrEstab"
,
SCTP_MIB_CURRESTAB
),
SNMP_MIB_ITEM
(
"SctpActiveEstabs"
,
SCTP_MIB_ACTIVEESTABS
),
SNMP_MIB_ITEM
(
"SctpPassiveEstabs"
,
SCTP_MIB_PASSIVEESTABS
),
...
...
net/sctp/protocol.c
View file @
cabbb4de
...
...
@@ -95,7 +95,7 @@ struct sock *sctp_get_ctl_sock(void)
}
/* Set up the proc fs entry for the SCTP protocol. */
__init
int
sctp_proc_init
(
void
)
static
__init
int
sctp_proc_init
(
void
)
{
if
(
!
proc_net_sctp
)
{
struct
proc_dir_entry
*
ent
;
...
...
@@ -124,7 +124,7 @@ __init int sctp_proc_init(void)
* Note: Do not make this __exit as it is used in the init error
* path.
*/
void
sctp_proc_exit
(
void
)
static
void
sctp_proc_exit
(
void
)
{
sctp_snmp_proc_exit
();
sctp_eps_proc_exit
();
...
...
@@ -428,9 +428,9 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
* addresses. If an association is passed, trys to get a dst entry with a
* source address that matches an address in the bind address list.
*/
struct
dst_entry
*
sctp_v4_get_dst
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
st
atic
st
ruct
dst_entry
*
sctp_v4_get_dst
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
{
struct
rtable
*
rt
;
struct
flowi
fl
;
...
...
@@ -520,10 +520,10 @@ struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
/* For v4, the source address is cached in the route entry(dst). So no need
* to cache it separately and hence this is an empty routine.
*/
void
sctp_v4_get_saddr
(
struct
sctp_association
*
asoc
,
struct
dst_entry
*
dst
,
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
static
void
sctp_v4_get_saddr
(
struct
sctp_association
*
asoc
,
struct
dst_entry
*
dst
,
union
sctp_addr
*
daddr
,
union
sctp_addr
*
saddr
)
{
struct
rtable
*
rt
=
(
struct
rtable
*
)
dst
;
...
...
@@ -547,8 +547,8 @@ static int sctp_v4_is_ce(const struct sk_buff *skb)
}
/* Create and initialize a new sk for the socket returned by accept(). */
struct
sock
*
sctp_v4_create_accept_sk
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
)
st
atic
st
ruct
sock
*
sctp_v4_create_accept_sk
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
)
{
struct
sock
*
newsk
;
struct
inet_sock
*
inet
=
inet_sk
(
sk
);
...
...
@@ -639,7 +639,7 @@ int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
* Initialize the control inode/socket with a control endpoint data
* structure. This endpoint is reserved exclusively for the OOTB processing.
*/
int
sctp_ctl_sock_init
(
void
)
static
int
sctp_ctl_sock_init
(
void
)
{
int
err
;
sa_family_t
family
;
...
...
@@ -808,7 +808,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb,
return
ip_queue_xmit
(
skb
,
ipfragok
);
}
struct
sctp_af
sctp_ipv4_specific
;
st
atic
st
ruct
sctp_af
sctp_ipv4_specific
;
static
struct
sctp_pf
sctp_pf_inet
=
{
.
event_msgname
=
sctp_inet_event_msgname
,
...
...
@@ -829,7 +829,7 @@ static struct notifier_block sctp_inetaddr_notifier = {
};
/* Socket operations. */
struct
proto_ops
inet_seqpacket_ops
=
{
st
atic
st
ruct
proto_ops
inet_seqpacket_ops
=
{
.
family
=
PF_INET
,
.
owner
=
THIS_MODULE
,
.
release
=
inet_release
,
/* Needs to be wrapped... */
...
...
@@ -878,7 +878,7 @@ static struct net_protocol sctp_protocol = {
};
/* IPv4 address related functions. */
struct
sctp_af
sctp_ipv4_specific
=
{
st
atic
st
ruct
sctp_af
sctp_ipv4_specific
=
{
.
sctp_xmit
=
sctp_v4_xmit
,
.
setsockopt
=
ip_setsockopt
,
.
getsockopt
=
ip_getsockopt
,
...
...
@@ -959,7 +959,7 @@ static void cleanup_sctp_mibs(void)
}
/* Initialize the universe into something sensible. */
__init
int
sctp_init
(
void
)
SCTP_STATIC
__init
int
sctp_init
(
void
)
{
int
i
;
int
status
=
-
EINVAL
;
...
...
@@ -1196,7 +1196,7 @@ __init int sctp_init(void)
}
/* Exit handler for the SCTP protocol. */
__exit
void
sctp_exit
(
void
)
SCTP_STATIC
__exit
void
sctp_exit
(
void
)
{
/* BUG. This should probably do something useful like clean
* up all the remaining associations and all that memory.
...
...
net/sctp/sm_make_chunk.c
View file @
cabbb4de
...
...
@@ -67,6 +67,19 @@
extern
kmem_cache_t
*
sctp_chunk_cachep
;
SCTP_STATIC
struct
sctp_chunk
*
sctp_make_chunk
(
const
struct
sctp_association
*
asoc
,
__u8
type
,
__u8
flags
,
int
paylen
);
static
sctp_cookie_param_t
*
sctp_pack_cookie
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_chunk
*
init_chunk
,
int
*
cookie_len
,
const
__u8
*
raw_addrs
,
int
addrs_len
);
static
int
sctp_process_param
(
struct
sctp_association
*
asoc
,
union
sctp_params
param
,
const
union
sctp_addr
*
peer_addr
,
int
gfp
);
/* What was the inbound interface for this chunk? */
int
sctp_chunk_iif
(
const
struct
sctp_chunk
*
chunk
)
{
...
...
@@ -559,52 +572,6 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
return
retval
;
}
/* Make a DATA chunk for the given association. Populate the data
* payload.
*/
struct
sctp_chunk
*
sctp_make_datafrag
(
struct
sctp_association
*
asoc
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
data_len
,
const
__u8
*
data
,
__u8
flags
,
__u16
ssn
)
{
struct
sctp_chunk
*
retval
;
retval
=
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
data_len
,
flags
,
ssn
);
if
(
retval
)
sctp_addto_chunk
(
retval
,
data_len
,
data
);
return
retval
;
}
/* Make a DATA chunk for the given association to ride on stream id
* 'stream', with a payload id of 'payload', and a body of 'data'.
*/
struct
sctp_chunk
*
sctp_make_data
(
struct
sctp_association
*
asoc
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
data_len
,
const
__u8
*
data
)
{
struct
sctp_chunk
*
retval
=
NULL
;
retval
=
sctp_make_data_empty
(
asoc
,
sinfo
,
data_len
);
if
(
retval
)
sctp_addto_chunk
(
retval
,
data_len
,
data
);
return
retval
;
}
/* Make a DATA chunk for the given association to ride on stream id
* 'stream', with a payload id of 'payload', and a body big enough to
* hold 'data_len' octets of data. We use this version when we need
* to build the message AFTER allocating memory.
*/
struct
sctp_chunk
*
sctp_make_data_empty
(
struct
sctp_association
*
asoc
,
const
struct
sctp_sndrcvinfo
*
sinfo
,
int
data_len
)
{
__u8
flags
=
SCTP_DATA_NOT_FRAG
;
return
sctp_make_datafrag_empty
(
asoc
,
sinfo
,
data_len
,
flags
,
0
);
}
/* Create a selective ackowledgement (SACK) for the given
* association. This reports on which TSN's we've seen to date,
* including duplicates and gaps.
...
...
@@ -881,6 +848,31 @@ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
return
retval
;
}
/* Make an ABORT chunk with a PROTOCOL VIOLATION cause code. */
struct
sctp_chunk
*
sctp_make_abort_violation
(
const
struct
sctp_association
*
asoc
,
const
struct
sctp_chunk
*
chunk
,
const
__u8
*
payload
,
const
size_t
paylen
)
{
struct
sctp_chunk
*
retval
;
struct
sctp_paramhdr
phdr
;
retval
=
sctp_make_abort
(
asoc
,
chunk
,
sizeof
(
sctp_errhdr_t
)
+
paylen
+
sizeof
(
sctp_chunkhdr_t
));
if
(
!
retval
)
goto
end
;
sctp_init_cause
(
retval
,
SCTP_ERROR_PROTO_VIOLATION
,
payload
,
paylen
);
phdr
.
type
=
htons
(
chunk
->
chunk_hdr
->
type
);
phdr
.
length
=
chunk
->
chunk_hdr
->
length
;
sctp_addto_chunk
(
retval
,
sizeof
(
sctp_paramhdr_t
),
&
phdr
);
end:
return
retval
;
}
/* Make a HEARTBEAT chunk. */
struct
sctp_chunk
*
sctp_make_heartbeat
(
const
struct
sctp_association
*
asoc
,
const
struct
sctp_transport
*
transport
,
...
...
@@ -933,7 +925,7 @@ struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *asoc,
/* Create an Operation Error chunk with the specified space reserved.
* This routine can be used for containing multiple causes in the chunk.
*/
struct
sctp_chunk
*
sctp_make_op_error_space
(
st
atic
st
ruct
sctp_chunk
*
sctp_make_op_error_space
(
const
struct
sctp_association
*
asoc
,
const
struct
sctp_chunk
*
chunk
,
size_t
size
)
...
...
@@ -1034,7 +1026,6 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
SCTP_DBG_OBJCNT_INC
(
chunk
);
atomic_set
(
&
retval
->
refcnt
,
1
);
nodata:
return
retval
;
}
...
...
@@ -1062,6 +1053,7 @@ const union sctp_addr *sctp_source(const struct sctp_chunk *chunk)
/* Create a new chunk, setting the type and flags headers from the
* arguments, reserving enough space for a 'paylen' byte payload.
*/
SCTP_STATIC
struct
sctp_chunk
*
sctp_make_chunk
(
const
struct
sctp_association
*
asoc
,
__u8
type
,
__u8
flags
,
int
paylen
)
{
...
...
@@ -1261,7 +1253,7 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
/* Build a cookie representing asoc.
* This INCLUDES the param header needed to put the cookie in the INIT ACK.
*/
sctp_cookie_param_t
*
sctp_pack_cookie
(
const
struct
sctp_endpoint
*
ep
,
s
tatic
s
ctp_cookie_param_t
*
sctp_pack_cookie
(
const
struct
sctp_endpoint
*
ep
,
const
struct
sctp_association
*
asoc
,
const
struct
sctp_chunk
*
init_chunk
,
int
*
cookie_len
,
...
...
@@ -1409,6 +1401,24 @@ struct sctp_association *sctp_unpack_cookie(
}
no_hmac:
/* IG Section 2.35.2:
* 3) Compare the port numbers and the verification tag contained
* within the COOKIE ECHO chunk to the actual port numbers and the
* verification tag within the SCTP common header of the received
* packet. If these values do not match the packet MUST be silently
* discarded,
*/
if
(
ntohl
(
chunk
->
sctp_hdr
->
vtag
)
!=
bear_cookie
->
my_vtag
)
{
*
error
=
-
SCTP_IERROR_BAD_TAG
;
goto
fail
;
}
if
(
ntohs
(
chunk
->
sctp_hdr
->
source
)
!=
bear_cookie
->
peer_addr
.
v4
.
sin_port
||
ntohs
(
chunk
->
sctp_hdr
->
dest
)
!=
bear_cookie
->
my_port
)
{
*
error
=
-
SCTP_IERROR_BAD_PORTS
;
goto
fail
;
}
/* Check to see if the cookie is stale. If there is already
* an association, there is no need to check cookie's expiration
* for init collision case of lost COOKIE ACK.
...
...
@@ -1547,6 +1557,30 @@ static int sctp_process_inv_mandatory(const struct sctp_association *asoc,
return
0
;
}
static
int
sctp_process_inv_paramlength
(
const
struct
sctp_association
*
asoc
,
struct
sctp_paramhdr
*
param
,
const
struct
sctp_chunk
*
chunk
,
struct
sctp_chunk
**
errp
)
{
char
error
[]
=
"The following parameter had invalid length:"
;
size_t
payload_len
=
WORD_ROUND
(
sizeof
(
error
))
+
sizeof
(
sctp_paramhdr_t
);
/* Create an error chunk and fill it in with our payload. */
if
(
!*
errp
)
*
errp
=
sctp_make_op_error_space
(
asoc
,
chunk
,
payload_len
);
if
(
*
errp
)
{
sctp_init_cause
(
*
errp
,
SCTP_ERROR_PROTO_VIOLATION
,
error
,
sizeof
(
error
));
sctp_addto_chunk
(
*
errp
,
sizeof
(
sctp_paramhdr_t
),
param
);
}
return
0
;
}
/* Do not attempt to handle the HOST_NAME parm. However, do
* send back an indicator to the peer.
*/
...
...
@@ -1725,6 +1759,18 @@ int sctp_verify_init(const struct sctp_association *asoc,
}
/* for (loop through all parameters) */
/* There is a possibility that a parameter length was bad and
* in that case we would have stoped walking the parameters.
* The current param.p would point at the bad one.
* Current consensus on the mailing list is to generate a PROTOCOL
* VIOLATION error. We build the ERROR chunk here and let the normal
* error handling code build and send the packet.
*/
if
(
param
.
v
<
(
void
*
)
chunk
->
chunk_end
-
sizeof
(
sctp_paramhdr_t
))
{
sctp_process_inv_paramlength
(
asoc
,
param
.
p
,
chunk
,
errp
);
return
0
;
}
/* The only missing mandatory param possible today is
* the state cookie for an INIT-ACK chunk.
*/
...
...
@@ -1912,8 +1958,10 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
* work we do. In particular, we should not build transport
* structures for the addresses.
*/
int
sctp_process_param
(
struct
sctp_association
*
asoc
,
union
sctp_params
param
,
const
union
sctp_addr
*
peer_addr
,
int
gfp
)
static
int
sctp_process_param
(
struct
sctp_association
*
asoc
,
union
sctp_params
param
,
const
union
sctp_addr
*
peer_addr
,
int
gfp
)
{
union
sctp_addr
addr
;
int
i
;
...
...
@@ -2078,8 +2126,9 @@ __u32 sctp_generate_tsn(const struct sctp_endpoint *ep)
*
* Address Parameter and other parameter will not be wrapped in this function
*/
struct
sctp_chunk
*
sctp_make_asconf
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
addr
,
int
vparam_len
)
static
struct
sctp_chunk
*
sctp_make_asconf
(
struct
sctp_association
*
asoc
,
union
sctp_addr
*
addr
,
int
vparam_len
)
{
sctp_addiphdr_t
asconf
;
struct
sctp_chunk
*
retval
;
...
...
@@ -2248,8 +2297,8 @@ struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
*
* Create an ASCONF_ACK chunk with enough space for the parameter responses.
*/
struct
sctp_chunk
*
sctp_make_asconf_ack
(
const
struct
sctp_association
*
asoc
,
__u32
serial
,
int
vparam_len
)
st
atic
st
ruct
sctp_chunk
*
sctp_make_asconf_ack
(
const
struct
sctp_association
*
asoc
,
__u32
serial
,
int
vparam_len
)
{
sctp_addiphdr_t
asconf
;
struct
sctp_chunk
*
retval
;
...
...
net/sctp/sm_sideeffect.c
View file @
cabbb4de
...
...
@@ -55,6 +55,24 @@
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
static
int
sctp_cmd_interpreter
(
sctp_event_t
event_type
,
sctp_subtype_t
subtype
,
sctp_state_t
state
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
,
void
*
event_arg
,
sctp_disposition_t
status
,
sctp_cmd_seq_t
*
commands
,
int
gfp
);
static
int
sctp_side_effects
(
sctp_event_t
event_type
,
sctp_subtype_t
subtype
,
sctp_state_t
state
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
,
void
*
event_arg
,
sctp_disposition_t
status
,
sctp_cmd_seq_t
*
commands
,
int
gfp
);
/********************************************************************
* Helper functions
********************************************************************/
...
...
@@ -134,8 +152,8 @@ static void sctp_do_ecn_cwr_work(struct sctp_association *asoc,
}
/* Generate SACK if necessary. We call this at the end of a packet. */
int
sctp_gen_sack
(
struct
sctp_association
*
asoc
,
int
force
,
sctp_cmd_seq_t
*
commands
)
static
int
sctp_gen_sack
(
struct
sctp_association
*
asoc
,
int
force
,
sctp_cmd_seq_t
*
commands
)
{
__u32
ctsn
,
max_tsn_seen
;
struct
sctp_chunk
*
sack
;
...
...
@@ -276,31 +294,31 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc,
sctp_association_put
(
asoc
);
}
void
sctp_generate_t1_cookie_event
(
unsigned
long
data
)
static
void
sctp_generate_t1_cookie_event
(
unsigned
long
data
)
{
struct
sctp_association
*
asoc
=
(
struct
sctp_association
*
)
data
;
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T1_COOKIE
);
}
void
sctp_generate_t1_init_event
(
unsigned
long
data
)
static
void
sctp_generate_t1_init_event
(
unsigned
long
data
)
{
struct
sctp_association
*
asoc
=
(
struct
sctp_association
*
)
data
;
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T1_INIT
);
}
void
sctp_generate_t2_shutdown_event
(
unsigned
long
data
)
static
void
sctp_generate_t2_shutdown_event
(
unsigned
long
data
)
{
struct
sctp_association
*
asoc
=
(
struct
sctp_association
*
)
data
;
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T2_SHUTDOWN
);
}
void
sctp_generate_t4_rto_event
(
unsigned
long
data
)
static
void
sctp_generate_t4_rto_event
(
unsigned
long
data
)
{
struct
sctp_association
*
asoc
=
(
struct
sctp_association
*
)
data
;
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_T4_RTO
);
}
void
sctp_generate_t5_shutdown_guard_event
(
unsigned
long
data
)
static
void
sctp_generate_t5_shutdown_guard_event
(
unsigned
long
data
)
{
struct
sctp_association
*
asoc
=
(
struct
sctp_association
*
)
data
;
sctp_generate_timeout_event
(
asoc
,
...
...
@@ -308,7 +326,7 @@ void sctp_generate_t5_shutdown_guard_event(unsigned long data)
}
/* sctp_generate_t5_shutdown_guard_event() */
void
sctp_generate_autoclose_event
(
unsigned
long
data
)
static
void
sctp_generate_autoclose_event
(
unsigned
long
data
)
{
struct
sctp_association
*
asoc
=
(
struct
sctp_association
*
)
data
;
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_AUTOCLOSE
);
...
...
@@ -353,7 +371,7 @@ void sctp_generate_heartbeat_event(unsigned long data)
}
/* Inject a SACK Timeout event into the state machine. */
void
sctp_generate_sack_event
(
unsigned
long
data
)
static
void
sctp_generate_sack_event
(
unsigned
long
data
)
{
struct
sctp_association
*
asoc
=
(
struct
sctp_association
*
)
data
;
sctp_generate_timeout_event
(
asoc
,
SCTP_EVENT_TIMEOUT_SACK
);
...
...
@@ -397,7 +415,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
asoc
->
overall_error_count
++
;
if
(
transport
->
active
&&
(
transport
->
error_count
++
>=
transport
->
error_threshold
))
{
(
transport
->
error_count
++
>=
transport
->
max_retrans
))
{
SCTP_DEBUG_PRINTK
(
"transport_strike: transport "
"IP:%d.%d.%d.%d failed.
\n
"
,
NIPQUAD
(
transport
->
ipaddr
.
v4
.
sin_addr
));
...
...
@@ -857,14 +875,14 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
/*****************************************************************
* This the master state function side effect processing function.
*****************************************************************/
int
sctp_side_effects
(
sctp_event_t
event_type
,
sctp_subtype_t
subtype
,
sctp_state_t
state
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
,
void
*
event_arg
,
sctp_disposition_t
status
,
sctp_cmd_seq_t
*
commands
,
int
gfp
)
static
int
sctp_side_effects
(
sctp_event_t
event_type
,
sctp_subtype_t
subtype
,
sctp_state_t
state
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
,
void
*
event_arg
,
sctp_disposition_t
status
,
sctp_cmd_seq_t
*
commands
,
int
gfp
)
{
int
error
;
...
...
@@ -944,11 +962,15 @@ int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
********************************************************************/
/* This is the side-effect interpreter. */
int
sctp_cmd_interpreter
(
sctp_event_t
event_type
,
sctp_subtype_t
subtype
,
sctp_state_t
state
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
,
void
*
event_arg
,
sctp_disposition_t
status
,
sctp_cmd_seq_t
*
commands
,
int
gfp
)
static
int
sctp_cmd_interpreter
(
sctp_event_t
event_type
,
sctp_subtype_t
subtype
,
sctp_state_t
state
,
struct
sctp_endpoint
*
ep
,
struct
sctp_association
*
asoc
,
void
*
event_arg
,
sctp_disposition_t
status
,
sctp_cmd_seq_t
*
commands
,
int
gfp
)
{
int
error
=
0
;
int
force
;
...
...
net/sctp/sm_statefuns.c
View file @
cabbb4de
This diff is collapsed.
Click to expand it.
net/sctp/sm_statetable.c
View file @
cabbb4de
...
...
@@ -50,6 +50,17 @@
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
static
const
sctp_sm_table_entry_t
primitive_event_table
[
SCTP_NUM_PRIMITIVE_TYPES
][
SCTP_STATE_NUM_STATES
];
static
const
sctp_sm_table_entry_t
other_event_table
[
SCTP_NUM_OTHER_TYPES
][
SCTP_STATE_NUM_STATES
];
static
const
sctp_sm_table_entry_t
timeout_event_table
[
SCTP_NUM_TIMEOUT_TYPES
][
SCTP_STATE_NUM_STATES
];
static
const
sctp_sm_table_entry_t
*
sctp_chunk_event_lookup
(
sctp_cid_t
cid
,
sctp_state_t
state
);
static
const
sctp_sm_table_entry_t
bug
=
{
.
fn
=
sctp_sf_bug
,
.
name
=
"sctp_sf_bug"
...
...
@@ -419,7 +430,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
*
* For base protocol (RFC 2960).
*/
const
sctp_sm_table_entry_t
chunk_event_table
[
SCTP_NUM_BASE_CHUNK_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
static
const
sctp_sm_table_entry_t
chunk_event_table
[
SCTP_NUM_BASE_CHUNK_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
TYPE_SCTP_DATA
,
TYPE_SCTP_INIT
,
TYPE_SCTP_INIT_ACK
,
...
...
@@ -482,7 +493,7 @@ const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_ST
/* The primary index for this table is the chunk type.
* The secondary index for this table is the state.
*/
const
sctp_sm_table_entry_t
addip_chunk_event_table
[
SCTP_NUM_ADDIP_CHUNK_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
static
const
sctp_sm_table_entry_t
addip_chunk_event_table
[
SCTP_NUM_ADDIP_CHUNK_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
TYPE_SCTP_ASCONF
,
TYPE_SCTP_ASCONF_ACK
,
};
/*state_fn_t addip_chunk_event_table[][] */
...
...
@@ -511,7 +522,7 @@ const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_TYPES][
/* The primary index for this table is the chunk type.
* The secondary index for this table is the state.
*/
const
sctp_sm_table_entry_t
prsctp_chunk_event_table
[
SCTP_NUM_PRSCTP_CHUNK_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
static
const
sctp_sm_table_entry_t
prsctp_chunk_event_table
[
SCTP_NUM_PRSCTP_CHUNK_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
TYPE_SCTP_FWD_TSN
,
};
/*state_fn_t prsctp_chunk_event_table[][] */
...
...
@@ -684,7 +695,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
/* The primary index for this table is the primitive type.
* The secondary index for this table is the state.
*/
const
sctp_sm_table_entry_t
primitive_event_table
[
SCTP_NUM_PRIMITIVE_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
static
const
sctp_sm_table_entry_t
primitive_event_table
[
SCTP_NUM_PRIMITIVE_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
TYPE_SCTP_PRIMITIVE_ASSOCIATE
,
TYPE_SCTP_PRIMITIVE_SHUTDOWN
,
TYPE_SCTP_PRIMITIVE_ABORT
,
...
...
@@ -716,8 +727,31 @@ const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP
{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
}
const
sctp_sm_table_entry_t
other_event_table
[
SCTP_NUM_OTHER_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
#define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH { \
/* SCTP_STATE_EMPTY */
\
{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
/* SCTP_STATE_CLOSED */
\
{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_COOKIE_WAIT */
\
{.fn = sctp_sf_cookie_wait_icmp_abort, \
.name = "sctp_sf_cookie_wait_icmp_abort"}, \
/* SCTP_STATE_COOKIE_ECHOED */
\
{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_ESTABLISHED */
\
{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_SHUTDOWN_PENDING */
\
{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_SHUTDOWN_SENT */
\
{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_SHUTDOWN_RECEIVED */
\
{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
/* SCTP_STATE_SHUTDOWN_ACK_SENT */
\
{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
}
static
const
sctp_sm_table_entry_t
other_event_table
[
SCTP_NUM_OTHER_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
TYPE_SCTP_OTHER_NO_PENDING_TSN
,
TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH
,
};
#define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
...
...
@@ -931,7 +965,7 @@ const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_N
{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
}
const
sctp_sm_table_entry_t
timeout_event_table
[
SCTP_NUM_TIMEOUT_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
static
const
sctp_sm_table_entry_t
timeout_event_table
[
SCTP_NUM_TIMEOUT_TYPES
][
SCTP_STATE_NUM_STATES
]
=
{
TYPE_SCTP_EVENT_TIMEOUT_NONE
,
TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE
,
TYPE_SCTP_EVENT_TIMEOUT_T1_INIT
,
...
...
@@ -944,8 +978,8 @@ const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STA
TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE
,
};
const
sctp_sm_table_entry_t
*
sctp_chunk_event_lookup
(
sctp_cid_t
cid
,
sctp_state_t
state
)
static
const
sctp_sm_table_entry_t
*
sctp_chunk_event_lookup
(
sctp_cid_t
cid
,
sctp_state_t
state
)
{
if
(
state
>
SCTP_STATE_MAX
)
return
&
bug
;
...
...
net/sctp/socket.c
View file @
cabbb4de
...
...
@@ -208,7 +208,7 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id)
* id are specified, the associations matching the address and the id should be
* the same.
*/
struct
sctp_transport
*
sctp_addr_id2transport
(
struct
sock
*
sk
,
st
atic
st
ruct
sctp_transport
*
sctp_addr_id2transport
(
struct
sock
*
sk
,
struct
sockaddr_storage
*
addr
,
sctp_assoc_t
id
)
{
...
...
@@ -245,7 +245,7 @@ struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
* sockaddr_in6 [RFC 2553]),
* addr_len - the size of the address structure.
*/
int
sctp_bind
(
struct
sock
*
sk
,
struct
sockaddr
*
uaddr
,
int
addr_len
)
SCTP_STATIC
int
sctp_bind
(
struct
sock
*
sk
,
struct
sockaddr
*
uaddr
,
int
addr_len
)
{
int
retval
=
0
;
...
...
@@ -343,8 +343,8 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
}
/* Refresh ephemeral port. */
if
(
!
snum
)
snum
=
inet_sk
(
sk
)
->
num
;
if
(
!
bp
->
port
)
bp
->
port
=
inet_sk
(
sk
)
->
num
;
/* Add the address to the bind address list. */
sctp_local_bh_disable
();
...
...
@@ -354,8 +354,6 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
addr
->
v4
.
sin_port
=
ntohs
(
addr
->
v4
.
sin_port
);
ret
=
sctp_add_bind_addr
(
bp
,
addr
,
GFP_ATOMIC
);
addr
->
v4
.
sin_port
=
htons
(
addr
->
v4
.
sin_port
);
if
(
!
ret
&&
!
bp
->
port
)
bp
->
port
=
snum
;
sctp_write_unlock
(
&
ep
->
base
.
addr_lock
);
sctp_local_bh_enable
();
...
...
@@ -1713,10 +1711,13 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
/* update default value for endpoint (all future associations) */
if
(
!
params
.
spp_assoc_id
&&
sctp_is_any
((
union
sctp_addr
*
)
&
params
.
spp_address
))
{
if
(
params
.
spp_hbinterval
)
/* Manual heartbeat on an endpoint is invalid. */
if
(
0xffffffff
==
params
.
spp_hbinterval
)
return
-
EINVAL
;
else
if
(
params
.
spp_hbinterval
)
sctp_sk
(
sk
)
->
paddrparam
.
spp_hbinterval
=
params
.
spp_hbinterval
;
if
(
sctp_max_retrans_path
)
if
(
params
.
spp_pathmaxrxt
)
sctp_sk
(
sk
)
->
paddrparam
.
spp_pathmaxrxt
=
params
.
spp_pathmaxrxt
;
return
0
;
...
...
@@ -1758,7 +1759,8 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
/* spp_pathmaxrxt contains the maximum number of retransmissions
* before this address shall be considered unreachable.
*/
trans
->
error_threshold
=
params
.
spp_pathmaxrxt
;
if
(
params
.
spp_pathmaxrxt
)
trans
->
max_retrans
=
params
.
spp_pathmaxrxt
;
return
0
;
}
...
...
@@ -2937,7 +2939,7 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
/* spp_pathmaxrxt contains the maximum number of retransmissions
* before this address shall be considered unreachable.
*/
params
.
spp_pathmaxrxt
=
trans
->
error_threshold
;
params
.
spp_pathmaxrxt
=
trans
->
max_retrans
;
done:
if
(
copy_to_user
(
optval
,
&
params
,
len
))
...
...
@@ -3049,6 +3051,9 @@ static int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
struct
sctp_bind_addr
*
bp
;
struct
sctp_association
*
asoc
;
struct
list_head
*
pos
;
struct
sctp_sockaddr_entry
*
addr
;
rwlock_t
*
addr_lock
;
unsigned
long
flags
;
int
cnt
=
0
;
if
(
len
!=
sizeof
(
sctp_assoc_t
))
...
...
@@ -3065,33 +3070,104 @@ static int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
*/
if
(
0
==
id
)
{
bp
=
&
sctp_sk
(
sk
)
->
ep
->
base
.
bind_addr
;
addr_lock
=
&
sctp_sk
(
sk
)
->
ep
->
base
.
addr_lock
;
}
else
{
asoc
=
sctp_id2assoc
(
sk
,
id
);
if
(
!
asoc
)
return
-
EINVAL
;
bp
=
&
asoc
->
base
.
bind_addr
;
addr_lock
=
&
asoc
->
base
.
addr_lock
;
}
sctp_read_lock
(
addr_lock
);
/* If the endpoint is bound to 0.0.0.0 or ::0, count the valid
* addresses from the global local address list.
*/
if
(
sctp_list_single_entry
(
&
bp
->
address_list
))
{
addr
=
list_entry
(
bp
->
address_list
.
next
,
struct
sctp_sockaddr_entry
,
list
);
if
(
sctp_is_any
(
&
addr
->
a
))
{
sctp_spin_lock_irqsave
(
&
sctp_local_addr_lock
,
flags
);
list_for_each
(
pos
,
&
sctp_local_addr_list
)
{
addr
=
list_entry
(
pos
,
struct
sctp_sockaddr_entry
,
list
);
if
((
PF_INET
==
sk
->
sk_family
)
&&
(
AF_INET6
==
addr
->
a
.
sa
.
sa_family
))
continue
;
cnt
++
;
}
sctp_spin_unlock_irqrestore
(
&
sctp_local_addr_lock
,
flags
);
}
else
{
cnt
=
1
;
}
goto
done
;
}
list_for_each
(
pos
,
&
bp
->
address_list
)
{
cnt
++
;
}
done:
sctp_read_unlock
(
addr_lock
);
return
cnt
;
}
/* Helper function that copies local addresses to user and returns the number
* of addresses copied.
*/
static
int
sctp_copy_laddrs_to_user
(
struct
sock
*
sk
,
__u16
port
,
int
max_addrs
,
void
__user
*
to
)
{
struct
list_head
*
pos
;
struct
sctp_sockaddr_entry
*
addr
;
unsigned
long
flags
;
union
sctp_addr
temp
;
int
cnt
=
0
;
int
addrlen
;
sctp_spin_lock_irqsave
(
&
sctp_local_addr_lock
,
flags
);
list_for_each
(
pos
,
&
sctp_local_addr_list
)
{
addr
=
list_entry
(
pos
,
struct
sctp_sockaddr_entry
,
list
);
if
((
PF_INET
==
sk
->
sk_family
)
&&
(
AF_INET6
==
addr
->
a
.
sa
.
sa_family
))
continue
;
memcpy
(
&
temp
,
&
addr
->
a
,
sizeof
(
temp
));
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sctp_sk
(
sk
),
&
temp
);
addrlen
=
sctp_get_af_specific
(
temp
.
sa
.
sa_family
)
->
sockaddr_len
;
temp
.
v4
.
sin_port
=
htons
(
port
);
if
(
copy_to_user
(
to
,
&
temp
,
addrlen
))
{
sctp_spin_unlock_irqrestore
(
&
sctp_local_addr_lock
,
flags
);
return
-
EFAULT
;
}
to
+=
addrlen
;
cnt
++
;
if
(
cnt
>=
max_addrs
)
break
;
}
sctp_spin_unlock_irqrestore
(
&
sctp_local_addr_lock
,
flags
);
return
cnt
;
}
static
int
sctp_getsockopt_local_addrs
(
struct
sock
*
sk
,
int
len
,
char
__user
*
optval
,
int
__user
*
optlen
)
char
__user
*
optval
,
int
__user
*
optlen
)
{
struct
sctp_bind_addr
*
bp
;
struct
sctp_association
*
asoc
;
struct
list_head
*
pos
;
int
cnt
=
0
;
struct
sctp_getaddrs
getaddrs
;
struct
sctp_sockaddr_entry
*
from
;
struct
sctp_sockaddr_entry
*
addr
;
void
__user
*
to
;
union
sctp_addr
temp
;
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
int
addrlen
;
rwlock_t
*
addr_lock
;
int
err
=
0
;
if
(
len
!=
sizeof
(
struct
sctp_getaddrs
))
return
-
EINVAL
;
...
...
@@ -3108,33 +3184,59 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
*/
if
(
0
==
getaddrs
.
assoc_id
)
{
bp
=
&
sctp_sk
(
sk
)
->
ep
->
base
.
bind_addr
;
addr_lock
=
&
sctp_sk
(
sk
)
->
ep
->
base
.
addr_lock
;
}
else
{
asoc
=
sctp_id2assoc
(
sk
,
getaddrs
.
assoc_id
);
if
(
!
asoc
)
return
-
EINVAL
;
bp
=
&
asoc
->
base
.
bind_addr
;
addr_lock
=
&
asoc
->
base
.
addr_lock
;
}
to
=
getaddrs
.
addrs
;
sctp_read_lock
(
addr_lock
);
/* If the endpoint is bound to 0.0.0.0 or ::0, get the valid
* addresses from the global local address list.
*/
if
(
sctp_list_single_entry
(
&
bp
->
address_list
))
{
addr
=
list_entry
(
bp
->
address_list
.
next
,
struct
sctp_sockaddr_entry
,
list
);
if
(
sctp_is_any
(
&
addr
->
a
))
{
cnt
=
sctp_copy_laddrs_to_user
(
sk
,
bp
->
port
,
getaddrs
.
addr_num
,
to
);
if
(
cnt
<
0
)
{
err
=
cnt
;
goto
unlock
;
}
goto
copy_getaddrs
;
}
}
list_for_each
(
pos
,
&
bp
->
address_list
)
{
from
=
list_entry
(
pos
,
struct
sctp_sockaddr_entry
,
list
);
memcpy
(
&
temp
,
&
from
->
a
,
sizeof
(
temp
));
addr
=
list_entry
(
pos
,
struct
sctp_sockaddr_entry
,
list
);
memcpy
(
&
temp
,
&
addr
->
a
,
sizeof
(
temp
));
sctp_get_pf_specific
(
sk
->
sk_family
)
->
addr_v4map
(
sp
,
&
temp
);
addrlen
=
sctp_get_af_specific
(
temp
.
sa
.
sa_family
)
->
sockaddr_len
;
temp
.
v4
.
sin_port
=
htons
(
temp
.
v4
.
sin_port
);
if
(
copy_to_user
(
to
,
&
temp
,
addrlen
))
return
-
EFAULT
;
if
(
copy_to_user
(
to
,
&
temp
,
addrlen
))
{
err
=
-
EFAULT
;
goto
unlock
;
}
to
+=
addrlen
;
cnt
++
;
if
(
cnt
>=
getaddrs
.
addr_num
)
break
;
}
copy_getaddrs:
getaddrs
.
addr_num
=
cnt
;
if
(
copy_to_user
(
optval
,
&
getaddrs
,
sizeof
(
struct
sctp_getaddrs
)))
return
-
EFAULT
;
err
=
-
EFAULT
;
return
0
;
unlock:
sctp_read_unlock
(
addr_lock
);
return
err
;
}
/* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR)
...
...
net/sctp/ssnmap.c
View file @
cabbb4de
...
...
@@ -42,6 +42,9 @@
#define MAX_KMALLOC_SIZE 131072
static
struct
sctp_ssnmap
*
sctp_ssnmap_init
(
struct
sctp_ssnmap
*
map
,
__u16
in
,
__u16
out
);
/* Storage size needed for map includes 2 headers and then the
* specific needs of in or out streams.
*/
...
...
@@ -87,8 +90,8 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int gfp)
/* Initialize a block of memory as a ssnmap. */
struct
sctp_ssnmap
*
sctp_ssnmap_init
(
struct
sctp_ssnmap
*
map
,
__u16
in
,
__u16
out
)
st
atic
st
ruct
sctp_ssnmap
*
sctp_ssnmap_init
(
struct
sctp_ssnmap
*
map
,
__u16
in
,
__u16
out
)
{
memset
(
map
,
0x00
,
sctp_ssnmap_size
(
in
,
out
));
...
...
net/sctp/transport.c
View file @
cabbb4de
...
...
@@ -54,34 +54,10 @@
/* 1st Level Abstractions. */
/* Allocate and initialize a new transport. */
struct
sctp_transport
*
sctp_transport_new
(
const
union
sctp_addr
*
addr
,
int
gfp
)
{
struct
sctp_transport
*
transport
;
transport
=
t_new
(
struct
sctp_transport
,
gfp
);
if
(
!
transport
)
goto
fail
;
if
(
!
sctp_transport_init
(
transport
,
addr
,
gfp
))
goto
fail_init
;
transport
->
malloced
=
1
;
SCTP_DBG_OBJCNT_INC
(
transport
);
return
transport
;
fail_init:
kfree
(
transport
);
fail:
return
NULL
;
}
/* Initialize a new transport from provided memory. */
struct
sctp_transport
*
sctp_transport_init
(
struct
sctp_transport
*
peer
,
const
union
sctp_addr
*
addr
,
int
gfp
)
st
atic
st
ruct
sctp_transport
*
sctp_transport_init
(
struct
sctp_transport
*
peer
,
const
union
sctp_addr
*
addr
,
int
gfp
)
{
/* Copy in the address. */
peer
->
ipaddr
=
*
addr
;
...
...
@@ -112,7 +88,6 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
/* Initialize the default path max_retrans. */
peer
->
max_retrans
=
sctp_max_retrans_path
;
peer
->
error_threshold
=
0
;
peer
->
error_count
=
0
;
INIT_LIST_HEAD
(
&
peer
->
transmitted
);
...
...
@@ -144,6 +119,30 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
return
peer
;
}
/* Allocate and initialize a new transport. */
struct
sctp_transport
*
sctp_transport_new
(
const
union
sctp_addr
*
addr
,
int
gfp
)
{
struct
sctp_transport
*
transport
;
transport
=
t_new
(
struct
sctp_transport
,
gfp
);
if
(
!
transport
)
goto
fail
;
if
(
!
sctp_transport_init
(
transport
,
addr
,
gfp
))
goto
fail_init
;
transport
->
malloced
=
1
;
SCTP_DBG_OBJCNT_INC
(
transport
);
return
transport
;
fail_init:
kfree
(
transport
);
fail:
return
NULL
;
}
/* This transport is no longer needed. Free up if possible, or
* delay until it last reference count.
*/
...
...
@@ -155,13 +154,23 @@ void sctp_transport_free(struct sctp_transport *transport)
if
(
del_timer
(
&
transport
->
hb_timer
))
sctp_transport_put
(
transport
);
/* Delete the T3_rtx timer if it's active.
* There is no point in not doing this now and letting
* structure hang around in memory since we know
* the tranport is going away.
*/
if
(
timer_pending
(
&
transport
->
T3_rtx_timer
)
&&
del_timer
(
&
transport
->
T3_rtx_timer
))
sctp_transport_put
(
transport
);
sctp_transport_put
(
transport
);
}
/* Destroy the transport data structure.
* Assumes there are no more users of this structure.
*/
void
sctp_transport_destroy
(
struct
sctp_transport
*
transport
)
static
void
sctp_transport_destroy
(
struct
sctp_transport
*
transport
)
{
SCTP_ASSERT
(
transport
->
dead
,
"Transport is not dead"
,
return
);
...
...
net/sctp/tsnmap.c
View file @
cabbb4de
...
...
@@ -52,29 +52,6 @@ static void sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off,
int
*
started
,
__u16
*
start
,
int
*
ended
,
__u16
*
end
);
/* Create a new sctp_tsnmap.
* Allocate room to store at least 'len' contiguous TSNs.
*/
struct
sctp_tsnmap
*
sctp_tsnmap_new
(
__u16
len
,
__u32
initial_tsn
,
int
gfp
)
{
struct
sctp_tsnmap
*
retval
;
retval
=
kmalloc
(
sizeof
(
struct
sctp_tsnmap
)
+
sctp_tsnmap_storage_size
(
len
),
gfp
);
if
(
!
retval
)
goto
fail
;
if
(
!
sctp_tsnmap_init
(
retval
,
len
,
initial_tsn
))
goto
fail_map
;
retval
->
malloced
=
1
;
return
retval
;
fail_map:
kfree
(
retval
);
fail:
return
NULL
;
}
/* Initialize a block of memory as a tsnmap. */
struct
sctp_tsnmap
*
sctp_tsnmap_init
(
struct
sctp_tsnmap
*
map
,
__u16
len
,
__u32
initial_tsn
)
...
...
@@ -168,16 +145,9 @@ void sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn)
}
/* Dispose of a tsnmap. */
void
sctp_tsnmap_free
(
struct
sctp_tsnmap
*
map
)
{
if
(
map
->
malloced
)
kfree
(
map
);
}
/* Initialize a Gap Ack Block iterator from memory being provided. */
void
sctp_tsnmap_iter_init
(
const
struct
sctp_tsnmap
*
map
,
struct
sctp_tsnmap_iter
*
iter
)
SCTP_STATIC
void
sctp_tsnmap_iter_init
(
const
struct
sctp_tsnmap
*
map
,
struct
sctp_tsnmap_iter
*
iter
)
{
/* Only start looking one past the Cumulative TSN Ack Point. */
iter
->
start
=
map
->
cumulative_tsn_ack_point
+
1
;
...
...
@@ -186,8 +156,9 @@ void sctp_tsnmap_iter_init(const struct sctp_tsnmap *map,
/* Get the next Gap Ack Blocks. Returns 0 if there was not another block
* to get.
*/
int
sctp_tsnmap_next_gap_ack
(
const
struct
sctp_tsnmap
*
map
,
struct
sctp_tsnmap_iter
*
iter
,
__u16
*
start
,
__u16
*
end
)
SCTP_STATIC
int
sctp_tsnmap_next_gap_ack
(
const
struct
sctp_tsnmap
*
map
,
struct
sctp_tsnmap_iter
*
iter
,
__u16
*
start
,
__u16
*
end
)
{
int
started
,
ended
;
__u16
_start
,
_end
,
offset
;
...
...
net/sctp/ulpevent.c
View file @
cabbb4de
...
...
@@ -65,8 +65,16 @@ static void sctp_stub_rfree(struct sk_buff *skb)
*/
}
/* Initialize an ULP event from an given skb. */
SCTP_STATIC
void
sctp_ulpevent_init
(
struct
sctp_ulpevent
*
event
,
int
msg_flags
)
{
memset
(
event
,
0
,
sizeof
(
struct
sctp_ulpevent
));
event
->
msg_flags
=
msg_flags
;
}
/* Create a new sctp_ulpevent. */
struct
sctp_ulpevent
*
sctp_ulpevent_new
(
int
size
,
int
msg_flags
,
int
gfp
)
SCTP_STATIC
struct
sctp_ulpevent
*
sctp_ulpevent_new
(
int
size
,
int
msg_flags
,
int
gfp
)
{
struct
sctp_ulpevent
*
event
;
struct
sk_buff
*
skb
;
...
...
@@ -84,13 +92,6 @@ struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, int gfp)
return
NULL
;
}
/* Initialize an ULP event from an given skb. */
void
sctp_ulpevent_init
(
struct
sctp_ulpevent
*
event
,
int
msg_flags
)
{
memset
(
event
,
0
,
sizeof
(
struct
sctp_ulpevent
));
event
->
msg_flags
=
msg_flags
;
}
/* Is this a MSG_NOTIFICATION? */
int
sctp_ulpevent_is_notification
(
const
struct
sctp_ulpevent
*
event
)
{
...
...
net/sctp/ulpqueue.c
View file @
cabbb4de
...
...
@@ -56,25 +56,6 @@ static struct sctp_ulpevent * sctp_ulpq_order(struct sctp_ulpq *,
/* 1st Level Abstractions */
/* Create a new ULP queue. */
struct
sctp_ulpq
*
sctp_ulpq_new
(
struct
sctp_association
*
asoc
,
int
gfp
)
{
struct
sctp_ulpq
*
ulpq
;
ulpq
=
kmalloc
(
sizeof
(
struct
sctp_ulpq
),
gfp
);
if
(
!
ulpq
)
goto
fail
;
if
(
!
sctp_ulpq_init
(
ulpq
,
asoc
))
goto
fail_init
;
ulpq
->
malloced
=
1
;
return
ulpq
;
fail_init:
kfree
(
ulpq
);
fail:
return
NULL
;
}
/* Initialize a ULP queue from a block of memory. */
struct
sctp_ulpq
*
sctp_ulpq_init
(
struct
sctp_ulpq
*
ulpq
,
struct
sctp_association
*
asoc
)
...
...
@@ -92,7 +73,7 @@ struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *ulpq,
/* Flush the reassembly and ordering queues. */
void
sctp_ulpq_flush
(
struct
sctp_ulpq
*
ulpq
)
static
void
sctp_ulpq_flush
(
struct
sctp_ulpq
*
ulpq
)
{
struct
sk_buff
*
skb
;
struct
sctp_ulpevent
*
event
;
...
...
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