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
79af02c2
Commit
79af02c2
authored
Jul 08, 2005
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SCTP]: Use struct list_head for chunk lists, not sk_buff_head.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
9c05989b
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
86 additions
and
66 deletions
+86
-66
include/net/sctp/structs.h
include/net/sctp/structs.h
+7
-13
net/sctp/associola.c
net/sctp/associola.c
+1
-1
net/sctp/input.c
net/sctp/input.c
+16
-10
net/sctp/inqueue.c
net/sctp/inqueue.c
+12
-6
net/sctp/output.c
net/sctp/output.c
+13
-9
net/sctp/outqueue.c
net/sctp/outqueue.c
+28
-22
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+8
-4
net/sctp/socket.c
net/sctp/socket.c
+1
-1
No files found.
include/net/sctp/structs.h
View file @
79af02c2
...
@@ -582,7 +582,6 @@ void sctp_datamsg_track(struct sctp_chunk *);
...
@@ -582,7 +582,6 @@ void sctp_datamsg_track(struct sctp_chunk *);
void
sctp_chunk_fail
(
struct
sctp_chunk
*
,
int
error
);
void
sctp_chunk_fail
(
struct
sctp_chunk
*
,
int
error
);
int
sctp_chunk_abandoned
(
struct
sctp_chunk
*
);
int
sctp_chunk_abandoned
(
struct
sctp_chunk
*
);
/* RFC2960 1.4 Key Terms
/* RFC2960 1.4 Key Terms
*
*
* o Chunk: A unit of information within an SCTP packet, consisting of
* o Chunk: A unit of information within an SCTP packet, consisting of
...
@@ -592,13 +591,8 @@ int sctp_chunk_abandoned(struct sctp_chunk *);
...
@@ -592,13 +591,8 @@ int sctp_chunk_abandoned(struct sctp_chunk *);
* each chunk as well as a few other header pointers...
* each chunk as well as a few other header pointers...
*/
*/
struct
sctp_chunk
{
struct
sctp_chunk
{
/* These first three elements MUST PRECISELY match the first
struct
list_head
list
;
* three elements of struct sk_buff. This allows us to reuse
* all the skb_* queue management functions.
*/
struct
sctp_chunk
*
next
;
struct
sctp_chunk
*
prev
;
struct
sk_buff_head
*
list
;
atomic_t
refcnt
;
atomic_t
refcnt
;
/* This is our link to the per-transport transmitted list. */
/* This is our link to the per-transport transmitted list. */
...
@@ -717,7 +711,7 @@ struct sctp_packet {
...
@@ -717,7 +711,7 @@ struct sctp_packet {
__u32
vtag
;
__u32
vtag
;
/* This contains the payload chunks. */
/* This contains the payload chunks. */
struct
sk_buff_head
chunks
;
struct
list_head
chunk_list
;
/* This is the overhead of the sctp and ip headers. */
/* This is the overhead of the sctp and ip headers. */
size_t
overhead
;
size_t
overhead
;
...
@@ -974,7 +968,7 @@ struct sctp_inq {
...
@@ -974,7 +968,7 @@ struct sctp_inq {
/* This is actually a queue of sctp_chunk each
/* This is actually a queue of sctp_chunk each
* containing a partially decoded packet.
* containing a partially decoded packet.
*/
*/
struct
sk_buff_head
in
;
struct
list_head
in_chunk_list
;
/* This is the packet which is currently off the in queue and is
/* This is the packet which is currently off the in queue and is
* being worked on through the inbound chunk processing.
* being worked on through the inbound chunk processing.
*/
*/
...
@@ -1017,7 +1011,7 @@ struct sctp_outq {
...
@@ -1017,7 +1011,7 @@ struct sctp_outq {
struct
sctp_association
*
asoc
;
struct
sctp_association
*
asoc
;
/* Data pending that has never been transmitted. */
/* Data pending that has never been transmitted. */
struct
sk_buff_head
ou
t
;
struct
list_head
out_chunk_lis
t
;
unsigned
out_qlen
;
/* Total length of queued data chunks. */
unsigned
out_qlen
;
/* Total length of queued data chunks. */
...
@@ -1025,7 +1019,7 @@ struct sctp_outq {
...
@@ -1025,7 +1019,7 @@ struct sctp_outq {
unsigned
error
;
unsigned
error
;
/* These are control chunks we want to send. */
/* These are control chunks we want to send. */
struct
sk_buff_head
control
;
struct
list_head
control_chunk_list
;
/* These are chunks that have been sacked but are above the
/* These are chunks that have been sacked but are above the
* CTSN, or cumulative tsn ack point.
* CTSN, or cumulative tsn ack point.
...
@@ -1672,7 +1666,7 @@ struct sctp_association {
...
@@ -1672,7 +1666,7 @@ struct sctp_association {
* which already resides in sctp_outq. Please move this
* which already resides in sctp_outq. Please move this
* queue and its supporting logic down there. --piggy]
* queue and its supporting logic down there. --piggy]
*/
*/
struct
sk_buff_head
addip_chunks
;
struct
list_head
addip_chunk_list
;
/* ADDIP Section 4.1 ASCONF Chunk Procedures
/* ADDIP Section 4.1 ASCONF Chunk Procedures
*
*
...
...
net/sctp/associola.c
View file @
79af02c2
...
@@ -203,7 +203,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
...
@@ -203,7 +203,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
*/
*/
asoc
->
addip_serial
=
asoc
->
c
.
initial_tsn
;
asoc
->
addip_serial
=
asoc
->
c
.
initial_tsn
;
skb_queue_head_init
(
&
asoc
->
addip_chunks
);
INIT_LIST_HEAD
(
&
asoc
->
addip_chunk_list
);
/* Make an empty list of remote transport addresses. */
/* Make an empty list of remote transport addresses. */
INIT_LIST_HEAD
(
&
asoc
->
peer
.
transport_addr_list
);
INIT_LIST_HEAD
(
&
asoc
->
peer
.
transport_addr_list
);
...
...
net/sctp/input.c
View file @
79af02c2
...
@@ -115,6 +115,17 @@ static void sctp_rcv_set_owner_r(struct sk_buff *skb, struct sock *sk)
...
@@ -115,6 +115,17 @@ static void sctp_rcv_set_owner_r(struct sk_buff *skb, struct sock *sk)
atomic_add
(
sizeof
(
struct
sctp_chunk
),
&
sk
->
sk_rmem_alloc
);
atomic_add
(
sizeof
(
struct
sctp_chunk
),
&
sk
->
sk_rmem_alloc
);
}
}
struct
sctp_input_cb
{
union
{
struct
inet_skb_parm
h4
;
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
struct
inet6_skb_parm
h6
;
#endif
}
header
;
struct
sctp_chunk
*
chunk
;
};
#define SCTP_INPUT_CB(__skb) ((struct sctp_input_cb *)&((__skb)->cb[0]))
/*
/*
* This is the routine which IP calls when receiving an SCTP packet.
* This is the routine which IP calls when receiving an SCTP packet.
*/
*/
...
@@ -243,6 +254,7 @@ int sctp_rcv(struct sk_buff *skb)
...
@@ -243,6 +254,7 @@ int sctp_rcv(struct sk_buff *skb)
ret
=
-
ENOMEM
;
ret
=
-
ENOMEM
;
goto
discard_release
;
goto
discard_release
;
}
}
SCTP_INPUT_CB
(
skb
)
->
chunk
=
chunk
;
sctp_rcv_set_owner_r
(
skb
,
sk
);
sctp_rcv_set_owner_r
(
skb
,
sk
);
...
@@ -265,9 +277,9 @@ int sctp_rcv(struct sk_buff *skb)
...
@@ -265,9 +277,9 @@ int sctp_rcv(struct sk_buff *skb)
sctp_bh_lock_sock
(
sk
);
sctp_bh_lock_sock
(
sk
);
if
(
sock_owned_by_user
(
sk
))
if
(
sock_owned_by_user
(
sk
))
sk_add_backlog
(
sk
,
(
struct
sk_buff
*
)
chunk
);
sk_add_backlog
(
sk
,
skb
);
else
else
sctp_backlog_rcv
(
sk
,
(
struct
sk_buff
*
)
chunk
);
sctp_backlog_rcv
(
sk
,
skb
);
/* Release the sock and any reference counts we took in the
/* Release the sock and any reference counts we took in the
* lookup calls.
* lookup calls.
...
@@ -302,14 +314,8 @@ int sctp_rcv(struct sk_buff *skb)
...
@@ -302,14 +314,8 @@ int sctp_rcv(struct sk_buff *skb)
*/
*/
int
sctp_backlog_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
int
sctp_backlog_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
{
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
=
SCTP_INPUT_CB
(
skb
)
->
chunk
;
struct
sctp_inq
*
inqueue
;
struct
sctp_inq
*
inqueue
=
&
chunk
->
rcvr
->
inqueue
;
/* One day chunk will live inside the skb, but for
* now this works.
*/
chunk
=
(
struct
sctp_chunk
*
)
skb
;
inqueue
=
&
chunk
->
rcvr
->
inqueue
;
sctp_inq_push
(
inqueue
,
chunk
);
sctp_inq_push
(
inqueue
,
chunk
);
return
0
;
return
0
;
...
...
net/sctp/inqueue.c
View file @
79af02c2
...
@@ -50,7 +50,7 @@
...
@@ -50,7 +50,7 @@
/* Initialize an SCTP inqueue. */
/* Initialize an SCTP inqueue. */
void
sctp_inq_init
(
struct
sctp_inq
*
queue
)
void
sctp_inq_init
(
struct
sctp_inq
*
queue
)
{
{
skb_queue_head_init
(
&
queue
->
in
);
INIT_LIST_HEAD
(
&
queue
->
in_chunk_list
);
queue
->
in_progress
=
NULL
;
queue
->
in_progress
=
NULL
;
/* Create a task for delivering data. */
/* Create a task for delivering data. */
...
@@ -62,11 +62,13 @@ void sctp_inq_init(struct sctp_inq *queue)
...
@@ -62,11 +62,13 @@ void sctp_inq_init(struct sctp_inq *queue)
/* Release the memory associated with an SCTP inqueue. */
/* Release the memory associated with an SCTP inqueue. */
void
sctp_inq_free
(
struct
sctp_inq
*
queue
)
void
sctp_inq_free
(
struct
sctp_inq
*
queue
)
{
{
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
,
*
tmp
;
/* Empty the queue. */
/* Empty the queue. */
while
((
chunk
=
(
struct
sctp_chunk
*
)
skb_dequeue
(
&
queue
->
in
))
!=
NULL
)
list_for_each_entry_safe
(
chunk
,
tmp
,
&
queue
->
in_chunk_list
,
list
)
{
list_del_init
(
&
chunk
->
list
);
sctp_chunk_free
(
chunk
);
sctp_chunk_free
(
chunk
);
}
/* If there is a packet which is currently being worked on,
/* If there is a packet which is currently being worked on,
* free it as well.
* free it as well.
...
@@ -92,7 +94,7 @@ void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *packet)
...
@@ -92,7 +94,7 @@ void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *packet)
* Eventually, we should clean up inqueue to not rely
* Eventually, we should clean up inqueue to not rely
* on the BH related data structures.
* on the BH related data structures.
*/
*/
skb_queue_tail
(
&
(
q
->
in
),
(
struct
sk_buff
*
)
packe
t
);
list_add_tail
(
&
packet
->
list
,
&
q
->
in_chunk_lis
t
);
q
->
immediate
.
func
(
q
->
immediate
.
data
);
q
->
immediate
.
func
(
q
->
immediate
.
data
);
}
}
...
@@ -131,12 +133,16 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
...
@@ -131,12 +133,16 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
/* Do we need to take the next packet out of the queue to process? */
/* Do we need to take the next packet out of the queue to process? */
if
(
!
chunk
)
{
if
(
!
chunk
)
{
struct
list_head
*
entry
;
/* Is the queue empty? */
/* Is the queue empty? */
if
(
skb_queue_empty
(
&
queue
->
in
))
if
(
list_empty
(
&
queue
->
in_chunk_list
))
return
NULL
;
return
NULL
;
entry
=
queue
->
in_chunk_list
.
next
;
chunk
=
queue
->
in_progress
=
chunk
=
queue
->
in_progress
=
(
struct
sctp_chunk
*
)
skb_dequeue
(
&
queue
->
in
);
list_entry
(
entry
,
struct
sctp_chunk
,
list
);
list_del_init
(
entry
);
/* This is the first chunk in the packet. */
/* This is the first chunk in the packet. */
chunk
->
singleton
=
1
;
chunk
->
singleton
=
1
;
...
...
net/sctp/output.c
View file @
79af02c2
...
@@ -108,7 +108,7 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
...
@@ -108,7 +108,7 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
packet
->
transport
=
transport
;
packet
->
transport
=
transport
;
packet
->
source_port
=
sport
;
packet
->
source_port
=
sport
;
packet
->
destination_port
=
dport
;
packet
->
destination_port
=
dport
;
skb_queue_head_init
(
&
packet
->
chunks
);
INIT_LIST_HEAD
(
&
packet
->
chunk_list
);
if
(
asoc
)
{
if
(
asoc
)
{
struct
sctp_sock
*
sp
=
sctp_sk
(
asoc
->
base
.
sk
);
struct
sctp_sock
*
sp
=
sctp_sk
(
asoc
->
base
.
sk
);
overhead
=
sp
->
pf
->
af
->
net_header_len
;
overhead
=
sp
->
pf
->
af
->
net_header_len
;
...
@@ -129,12 +129,14 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
...
@@ -129,12 +129,14 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
/* Free a packet. */
/* Free a packet. */
void
sctp_packet_free
(
struct
sctp_packet
*
packet
)
void
sctp_packet_free
(
struct
sctp_packet
*
packet
)
{
{
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
,
*
tmp
;
SCTP_DEBUG_PRINTK
(
"%s: packet:%p
\n
"
,
__FUNCTION__
,
packet
);
SCTP_DEBUG_PRINTK
(
"%s: packet:%p
\n
"
,
__FUNCTION__
,
packet
);
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
))
!=
NULL
)
list_for_each_entry_safe
(
chunk
,
tmp
,
&
packet
->
chunk_list
,
list
)
{
list_del_init
(
&
chunk
->
list
);
sctp_chunk_free
(
chunk
);
sctp_chunk_free
(
chunk
);
}
if
(
packet
->
malloced
)
if
(
packet
->
malloced
)
kfree
(
packet
);
kfree
(
packet
);
...
@@ -276,7 +278,7 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
...
@@ -276,7 +278,7 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
packet
->
has_sack
=
1
;
packet
->
has_sack
=
1
;
/* It is OK to send this chunk. */
/* It is OK to send this chunk. */
__skb_queue_tail
(
&
packet
->
chunks
,
(
struct
sk_buff
*
)
chunk
);
list_add_tail
(
&
chunk
->
list
,
&
packet
->
chunk_list
);
packet
->
size
+=
chunk_len
;
packet
->
size
+=
chunk_len
;
chunk
->
transport
=
packet
->
transport
;
chunk
->
transport
=
packet
->
transport
;
finish:
finish:
...
@@ -295,7 +297,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -295,7 +297,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
struct
sctphdr
*
sh
;
struct
sctphdr
*
sh
;
__u32
crc32
;
__u32
crc32
;
struct
sk_buff
*
nskb
;
struct
sk_buff
*
nskb
;
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
,
*
tmp
;
struct
sock
*
sk
;
struct
sock
*
sk
;
int
err
=
0
;
int
err
=
0
;
int
padding
;
/* How much padding do we need? */
int
padding
;
/* How much padding do we need? */
...
@@ -305,11 +307,11 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -305,11 +307,11 @@ int sctp_packet_transmit(struct sctp_packet *packet)
SCTP_DEBUG_PRINTK
(
"%s: packet:%p
\n
"
,
__FUNCTION__
,
packet
);
SCTP_DEBUG_PRINTK
(
"%s: packet:%p
\n
"
,
__FUNCTION__
,
packet
);
/* Do NOT generate a chunkless packet. */
/* Do NOT generate a chunkless packet. */
chunk
=
(
struct
sctp_chunk
*
)
skb_peek
(
&
packet
->
chunks
);
if
(
list_empty
(
&
packet
->
chunk_list
))
if
(
unlikely
(
!
chunk
))
return
err
;
return
err
;
/* Set up convenience variables... */
/* Set up convenience variables... */
chunk
=
list_entry
(
packet
->
chunk_list
.
next
,
struct
sctp_chunk
,
list
);
sk
=
chunk
->
skb
->
sk
;
sk
=
chunk
->
skb
->
sk
;
/* Allocate the new skb. */
/* Allocate the new skb. */
...
@@ -370,7 +372,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -370,7 +372,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* [This whole comment explains WORD_ROUND() below.]
* [This whole comment explains WORD_ROUND() below.]
*/
*/
SCTP_DEBUG_PRINTK
(
"***sctp_transmit_packet***
\n
"
);
SCTP_DEBUG_PRINTK
(
"***sctp_transmit_packet***
\n
"
);
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
))
!=
NULL
)
{
list_for_each_entry_safe
(
chunk
,
tmp
,
&
packet
->
chunk_list
,
list
)
{
list_del_init
(
&
chunk
->
list
);
if
(
sctp_chunk_is_data
(
chunk
))
{
if
(
sctp_chunk_is_data
(
chunk
))
{
if
(
!
chunk
->
has_tsn
)
{
if
(
!
chunk
->
has_tsn
)
{
...
@@ -511,7 +514,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
...
@@ -511,7 +514,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* will get resent or dropped later.
* will get resent or dropped later.
*/
*/
while
((
chunk
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
packet
->
chunks
))
!=
NULL
)
{
list_for_each_entry_safe
(
chunk
,
tmp
,
&
packet
->
chunk_list
,
list
)
{
list_del_init
(
&
chunk
->
list
);
if
(
!
sctp_chunk_is_data
(
chunk
))
if
(
!
sctp_chunk_is_data
(
chunk
))
sctp_chunk_free
(
chunk
);
sctp_chunk_free
(
chunk
);
}
}
...
...
net/sctp/outqueue.c
View file @
79af02c2
...
@@ -75,7 +75,7 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn);
...
@@ -75,7 +75,7 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn);
static
inline
void
sctp_outq_head_data
(
struct
sctp_outq
*
q
,
static
inline
void
sctp_outq_head_data
(
struct
sctp_outq
*
q
,
struct
sctp_chunk
*
ch
)
struct
sctp_chunk
*
ch
)
{
{
__skb_queue_head
(
&
q
->
out
,
(
struct
sk_buff
*
)
ch
);
list_add
(
&
ch
->
list
,
&
q
->
out_chunk_list
);
q
->
out_qlen
+=
ch
->
skb
->
len
;
q
->
out_qlen
+=
ch
->
skb
->
len
;
return
;
return
;
}
}
...
@@ -83,17 +83,22 @@ static inline void sctp_outq_head_data(struct sctp_outq *q,
...
@@ -83,17 +83,22 @@ static inline void sctp_outq_head_data(struct sctp_outq *q,
/* Take data from the front of the queue. */
/* Take data from the front of the queue. */
static
inline
struct
sctp_chunk
*
sctp_outq_dequeue_data
(
struct
sctp_outq
*
q
)
static
inline
struct
sctp_chunk
*
sctp_outq_dequeue_data
(
struct
sctp_outq
*
q
)
{
{
struct
sctp_chunk
*
ch
;
struct
sctp_chunk
*
ch
=
NULL
;
ch
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
q
->
out
);
if
(
ch
)
if
(
!
list_empty
(
&
q
->
out_chunk_list
))
{
struct
list_head
*
entry
=
q
->
out_chunk_list
.
next
;
ch
=
list_entry
(
entry
,
struct
sctp_chunk
,
list
);
list_del_init
(
entry
);
q
->
out_qlen
-=
ch
->
skb
->
len
;
q
->
out_qlen
-=
ch
->
skb
->
len
;
}
return
ch
;
return
ch
;
}
}
/* Add data chunk to the end of the queue. */
/* Add data chunk to the end of the queue. */
static
inline
void
sctp_outq_tail_data
(
struct
sctp_outq
*
q
,
static
inline
void
sctp_outq_tail_data
(
struct
sctp_outq
*
q
,
struct
sctp_chunk
*
ch
)
struct
sctp_chunk
*
ch
)
{
{
__skb_queue_tail
(
&
q
->
out
,
(
struct
sk_buff
*
)
ch
);
list_add_tail
(
&
ch
->
list
,
&
q
->
out_chunk_list
);
q
->
out_qlen
+=
ch
->
skb
->
len
;
q
->
out_qlen
+=
ch
->
skb
->
len
;
return
;
return
;
}
}
...
@@ -197,8 +202,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary,
...
@@ -197,8 +202,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary,
void
sctp_outq_init
(
struct
sctp_association
*
asoc
,
struct
sctp_outq
*
q
)
void
sctp_outq_init
(
struct
sctp_association
*
asoc
,
struct
sctp_outq
*
q
)
{
{
q
->
asoc
=
asoc
;
q
->
asoc
=
asoc
;
skb_queue_head_init
(
&
q
->
ou
t
);
INIT_LIST_HEAD
(
&
q
->
out_chunk_lis
t
);
skb_queue_head_init
(
&
q
->
control
);
INIT_LIST_HEAD
(
&
q
->
control_chunk_list
);
INIT_LIST_HEAD
(
&
q
->
retransmit
);
INIT_LIST_HEAD
(
&
q
->
retransmit
);
INIT_LIST_HEAD
(
&
q
->
sacked
);
INIT_LIST_HEAD
(
&
q
->
sacked
);
INIT_LIST_HEAD
(
&
q
->
abandoned
);
INIT_LIST_HEAD
(
&
q
->
abandoned
);
...
@@ -217,7 +222,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
...
@@ -217,7 +222,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
{
{
struct
sctp_transport
*
transport
;
struct
sctp_transport
*
transport
;
struct
list_head
*
lchunk
,
*
pos
,
*
temp
;
struct
list_head
*
lchunk
,
*
pos
,
*
temp
;
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
,
*
tmp
;
/* Throw away unacknowledged chunks. */
/* Throw away unacknowledged chunks. */
list_for_each
(
pos
,
&
q
->
asoc
->
peer
.
transport_addr_list
)
{
list_for_each
(
pos
,
&
q
->
asoc
->
peer
.
transport_addr_list
)
{
...
@@ -269,8 +274,10 @@ void sctp_outq_teardown(struct sctp_outq *q)
...
@@ -269,8 +274,10 @@ void sctp_outq_teardown(struct sctp_outq *q)
q
->
error
=
0
;
q
->
error
=
0
;
/* Throw away any leftover control chunks. */
/* Throw away any leftover control chunks. */
while
((
chunk
=
(
struct
sctp_chunk
*
)
skb_dequeue
(
&
q
->
control
))
!=
NULL
)
list_for_each_entry_safe
(
chunk
,
tmp
,
&
q
->
control_chunk_list
,
list
)
{
list_del_init
(
&
chunk
->
list
);
sctp_chunk_free
(
chunk
);
sctp_chunk_free
(
chunk
);
}
}
}
/* Free the outqueue structure and any related pending chunks. */
/* Free the outqueue structure and any related pending chunks. */
...
@@ -333,7 +340,7 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk)
...
@@ -333,7 +340,7 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk)
break
;
break
;
};
};
}
else
{
}
else
{
__skb_queue_tail
(
&
q
->
control
,
(
struct
sk_buff
*
)
chunk
);
list_add_tail
(
&
chunk
->
list
,
&
q
->
control_chunk_list
);
SCTP_INC_STATS
(
SCTP_MIB_OUTCTRLCHUNKS
);
SCTP_INC_STATS
(
SCTP_MIB_OUTCTRLCHUNKS
);
}
}
...
@@ -650,10 +657,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -650,10 +657,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
__u16
sport
=
asoc
->
base
.
bind_addr
.
port
;
__u16
sport
=
asoc
->
base
.
bind_addr
.
port
;
__u16
dport
=
asoc
->
peer
.
port
;
__u16
dport
=
asoc
->
peer
.
port
;
__u32
vtag
=
asoc
->
peer
.
i
.
init_tag
;
__u32
vtag
=
asoc
->
peer
.
i
.
init_tag
;
struct
sk_buff_head
*
queue
;
struct
sctp_transport
*
transport
=
NULL
;
struct
sctp_transport
*
transport
=
NULL
;
struct
sctp_transport
*
new_transport
;
struct
sctp_transport
*
new_transport
;
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
,
*
tmp
;
sctp_xmit_t
status
;
sctp_xmit_t
status
;
int
error
=
0
;
int
error
=
0
;
int
start_timer
=
0
;
int
start_timer
=
0
;
...
@@ -675,8 +681,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -675,8 +681,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
* ...
* ...
*/
*/
queue
=
&
q
->
control
;
list_for_each_entry_safe
(
chunk
,
tmp
,
&
q
->
control_chunk_list
,
list
)
{
while
((
chunk
=
(
struct
sctp_chunk
*
)
skb_dequeue
(
queue
))
!=
NULL
)
{
list_del_init
(
&
chunk
->
list
);
/* Pick the right transport to use. */
/* Pick the right transport to use. */
new_transport
=
chunk
->
transport
;
new_transport
=
chunk
->
transport
;
...
@@ -814,8 +821,6 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
...
@@ -814,8 +821,6 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
/* Finally, transmit new packets. */
/* Finally, transmit new packets. */
start_timer
=
0
;
start_timer
=
0
;
queue
=
&
q
->
out
;
while
((
chunk
=
sctp_outq_dequeue_data
(
q
))
!=
NULL
)
{
while
((
chunk
=
sctp_outq_dequeue_data
(
q
))
!=
NULL
)
{
/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
* stream identifier.
* stream identifier.
...
@@ -1149,8 +1154,9 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
...
@@ -1149,8 +1154,9 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
/* See if all chunks are acked.
/* See if all chunks are acked.
* Make sure the empty queue handler will get run later.
* Make sure the empty queue handler will get run later.
*/
*/
q
->
empty
=
skb_queue_empty
(
&
q
->
out
)
&&
skb_queue_empty
(
&
q
->
control
)
&&
q
->
empty
=
(
list_empty
(
&
q
->
out_chunk_list
)
&&
list_empty
(
&
q
->
retransmit
);
list_empty
(
&
q
->
control_chunk_list
)
&&
list_empty
(
&
q
->
retransmit
));
if
(
!
q
->
empty
)
if
(
!
q
->
empty
)
goto
finish
;
goto
finish
;
...
@@ -1729,7 +1735,7 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
...
@@ -1729,7 +1735,7 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
nskips
,
&
ftsn_skip_arr
[
0
]);
nskips
,
&
ftsn_skip_arr
[
0
]);
if
(
ftsn_chunk
)
{
if
(
ftsn_chunk
)
{
__skb_queue_tail
(
&
q
->
control
,
(
struct
sk_buff
*
)
ftsn_chunk
);
list_add_tail
(
&
ftsn_chunk
->
list
,
&
q
->
control_chunk_list
);
SCTP_INC_STATS
(
SCTP_MIB_OUTCTRLCHUNKS
);
SCTP_INC_STATS
(
SCTP_MIB_OUTCTRLCHUNKS
);
}
}
}
}
net/sctp/sm_make_chunk.c
View file @
79af02c2
...
@@ -1003,6 +1003,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
...
@@ -1003,6 +1003,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
SCTP_DEBUG_PRINTK
(
"chunkifying skb %p w/o an sk
\n
"
,
skb
);
SCTP_DEBUG_PRINTK
(
"chunkifying skb %p w/o an sk
\n
"
,
skb
);
}
}
INIT_LIST_HEAD
(
&
retval
->
list
);
retval
->
skb
=
skb
;
retval
->
skb
=
skb
;
retval
->
asoc
=
(
struct
sctp_association
*
)
asoc
;
retval
->
asoc
=
(
struct
sctp_association
*
)
asoc
;
retval
->
resent
=
0
;
retval
->
resent
=
0
;
...
@@ -1116,8 +1117,7 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk)
...
@@ -1116,8 +1117,7 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk)
/* Possibly, free the chunk. */
/* Possibly, free the chunk. */
void
sctp_chunk_free
(
struct
sctp_chunk
*
chunk
)
void
sctp_chunk_free
(
struct
sctp_chunk
*
chunk
)
{
{
/* Make sure that we are not on any list. */
BUG_ON
(
!
list_empty
(
&
chunk
->
list
));
skb_unlink
((
struct
sk_buff
*
)
chunk
);
list_del_init
(
&
chunk
->
transmitted_list
);
list_del_init
(
&
chunk
->
transmitted_list
);
/* Release our reference on the message tracker. */
/* Release our reference on the message tracker. */
...
@@ -2739,8 +2739,12 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
...
@@ -2739,8 +2739,12 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
asoc
->
addip_last_asconf
=
NULL
;
asoc
->
addip_last_asconf
=
NULL
;
/* Send the next asconf chunk from the addip chunk queue. */
/* Send the next asconf chunk from the addip chunk queue. */
asconf
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
asoc
->
addip_chunks
);
if
(
!
list_empty
(
&
asoc
->
addip_chunk_list
))
{
if
(
asconf
)
{
struct
list_head
*
entry
=
asoc
->
addip_chunk_list
.
next
;
asconf
=
list_entry
(
entry
,
struct
sctp_chunk
,
list
);
list_del_init
(
entry
);
/* Hold the chunk until an ASCONF_ACK is received. */
/* Hold the chunk until an ASCONF_ACK is received. */
sctp_chunk_hold
(
asconf
);
sctp_chunk_hold
(
asconf
);
if
(
sctp_primitive_ASCONF
(
asoc
,
asconf
))
if
(
sctp_primitive_ASCONF
(
asoc
,
asconf
))
...
...
net/sctp/socket.c
View file @
79af02c2
...
@@ -406,7 +406,7 @@ static int sctp_send_asconf(struct sctp_association *asoc,
...
@@ -406,7 +406,7 @@ static int sctp_send_asconf(struct sctp_association *asoc,
* transmission.
* transmission.
*/
*/
if
(
asoc
->
addip_last_asconf
)
{
if
(
asoc
->
addip_last_asconf
)
{
__skb_queue_tail
(
&
asoc
->
addip_chunks
,
(
struct
sk_buff
*
)
chunk
);
list_add_tail
(
&
chunk
->
list
,
&
asoc
->
addip_chunk_list
);
goto
out
;
goto
out
;
}
}
...
...
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