Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
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
Hide 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 *);
void
sctp_chunk_fail
(
struct
sctp_chunk
*
,
int
error
);
int
sctp_chunk_abandoned
(
struct
sctp_chunk
*
);
/* RFC2960 1.4 Key Terms
*
* o Chunk: A unit of information within an SCTP packet, consisting of
...
...
@@ -592,13 +591,8 @@ int sctp_chunk_abandoned(struct sctp_chunk *);
* each chunk as well as a few other header pointers...
*/
struct
sctp_chunk
{
/* These first three elements MUST PRECISELY match the first
* 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
;
struct
list_head
list
;
atomic_t
refcnt
;
/* This is our link to the per-transport transmitted list. */
...
...
@@ -717,7 +711,7 @@ struct sctp_packet {
__u32
vtag
;
/* 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. */
size_t
overhead
;
...
...
@@ -974,7 +968,7 @@ struct sctp_inq {
/* This is actually a queue of sctp_chunk each
* 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
* being worked on through the inbound chunk processing.
*/
...
...
@@ -1017,7 +1011,7 @@ struct sctp_outq {
struct
sctp_association
*
asoc
;
/* 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. */
...
...
@@ -1025,7 +1019,7 @@ struct sctp_outq {
unsigned
error
;
/* 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
* CTSN, or cumulative tsn ack point.
...
...
@@ -1672,7 +1666,7 @@ struct sctp_association {
* which already resides in sctp_outq. Please move this
* 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
*
...
...
net/sctp/associola.c
View file @
79af02c2
...
...
@@ -203,7 +203,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
*/
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. */
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)
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.
*/
...
...
@@ -243,6 +254,7 @@ int sctp_rcv(struct sk_buff *skb)
ret
=
-
ENOMEM
;
goto
discard_release
;
}
SCTP_INPUT_CB
(
skb
)
->
chunk
=
chunk
;
sctp_rcv_set_owner_r
(
skb
,
sk
);
...
...
@@ -265,9 +277,9 @@ int sctp_rcv(struct sk_buff *skb)
sctp_bh_lock_sock
(
sk
);
if
(
sock_owned_by_user
(
sk
))
sk_add_backlog
(
sk
,
(
struct
sk_buff
*
)
chunk
);
sk_add_backlog
(
sk
,
skb
);
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
* lookup calls.
...
...
@@ -302,14 +314,8 @@ discard_release:
*/
int
sctp_backlog_rcv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
sctp_chunk
*
chunk
;
struct
sctp_inq
*
inqueue
;
/* One day chunk will live inside the skb, but for
* now this works.
*/
chunk
=
(
struct
sctp_chunk
*
)
skb
;
inqueue
=
&
chunk
->
rcvr
->
inqueue
;
struct
sctp_chunk
*
chunk
=
SCTP_INPUT_CB
(
skb
)
->
chunk
;
struct
sctp_inq
*
inqueue
=
&
chunk
->
rcvr
->
inqueue
;
sctp_inq_push
(
inqueue
,
chunk
);
return
0
;
...
...
net/sctp/inqueue.c
View file @
79af02c2
...
...
@@ -50,7 +50,7 @@
/* Initialize an SCTP inqueue. */
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
;
/* Create a task for delivering data. */
...
...
@@ -62,11 +62,13 @@ void sctp_inq_init(struct sctp_inq *queue)
/* Release the memory associated with an SCTP inqueue. */
void
sctp_inq_free
(
struct
sctp_inq
*
queue
)
{
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
,
*
tmp
;
/* 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
);
}
/* If there is a packet which is currently being worked on,
* free it as well.
...
...
@@ -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
* 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
);
}
...
...
@@ -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? */
if
(
!
chunk
)
{
struct
list_head
*
entry
;
/* Is the queue empty? */
if
(
skb_queue_empty
(
&
queue
->
in
))
if
(
list_empty
(
&
queue
->
in_chunk_list
))
return
NULL
;
entry
=
queue
->
in_chunk_list
.
next
;
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. */
chunk
->
singleton
=
1
;
...
...
net/sctp/output.c
View file @
79af02c2
...
...
@@ -108,7 +108,7 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
packet
->
transport
=
transport
;
packet
->
source_port
=
sport
;
packet
->
destination_port
=
dport
;
skb_queue_head_init
(
&
packet
->
chunks
);
INIT_LIST_HEAD
(
&
packet
->
chunk_list
);
if
(
asoc
)
{
struct
sctp_sock
*
sp
=
sctp_sk
(
asoc
->
base
.
sk
);
overhead
=
sp
->
pf
->
af
->
net_header_len
;
...
...
@@ -129,12 +129,14 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
/* Free a 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
);
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
);
}
if
(
packet
->
malloced
)
kfree
(
packet
);
...
...
@@ -276,7 +278,7 @@ append:
packet
->
has_sack
=
1
;
/* 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
;
chunk
->
transport
=
packet
->
transport
;
finish:
...
...
@@ -295,7 +297,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
struct
sctphdr
*
sh
;
__u32
crc32
;
struct
sk_buff
*
nskb
;
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
,
*
tmp
;
struct
sock
*
sk
;
int
err
=
0
;
int
padding
;
/* How much padding do we need? */
...
...
@@ -305,11 +307,11 @@ int sctp_packet_transmit(struct sctp_packet *packet)
SCTP_DEBUG_PRINTK
(
"%s: packet:%p
\n
"
,
__FUNCTION__
,
packet
);
/* Do NOT generate a chunkless packet. */
chunk
=
(
struct
sctp_chunk
*
)
skb_peek
(
&
packet
->
chunks
);
if
(
unlikely
(
!
chunk
))
if
(
list_empty
(
&
packet
->
chunk_list
))
return
err
;
/* Set up convenience variables... */
chunk
=
list_entry
(
packet
->
chunk_list
.
next
,
struct
sctp_chunk
,
list
);
sk
=
chunk
->
skb
->
sk
;
/* Allocate the new skb. */
...
...
@@ -370,7 +372,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* [This whole comment explains WORD_ROUND() below.]
*/
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
(
!
chunk
->
has_tsn
)
{
...
...
@@ -511,7 +514,8 @@ err:
* 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
))
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);
static
inline
void
sctp_outq_head_data
(
struct
sctp_outq
*
q
,
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
;
return
;
}
...
...
@@ -83,17 +83,22 @@ static inline void sctp_outq_head_data(struct sctp_outq *q,
/* Take data from the front of the queue. */
static
inline
struct
sctp_chunk
*
sctp_outq_dequeue_data
(
struct
sctp_outq
*
q
)
{
struct
sctp_chunk
*
ch
;
ch
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
q
->
out
);
if
(
ch
)
struct
sctp_chunk
*
ch
=
NULL
;
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
;
}
return
ch
;
}
/* Add data chunk to the end of the queue. */
static
inline
void
sctp_outq_tail_data
(
struct
sctp_outq
*
q
,
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
;
return
;
}
...
...
@@ -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
)
{
q
->
asoc
=
asoc
;
skb_queue_head_init
(
&
q
->
ou
t
);
skb_queue_head_init
(
&
q
->
control
);
INIT_LIST_HEAD
(
&
q
->
out_chunk_lis
t
);
INIT_LIST_HEAD
(
&
q
->
control_chunk_list
);
INIT_LIST_HEAD
(
&
q
->
retransmit
);
INIT_LIST_HEAD
(
&
q
->
sacked
);
INIT_LIST_HEAD
(
&
q
->
abandoned
);
...
...
@@ -217,7 +222,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
{
struct
sctp_transport
*
transport
;
struct
list_head
*
lchunk
,
*
pos
,
*
temp
;
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
,
*
tmp
;
/* Throw away unacknowledged chunks. */
list_for_each
(
pos
,
&
q
->
asoc
->
peer
.
transport_addr_list
)
{
...
...
@@ -269,8 +274,10 @@ void sctp_outq_teardown(struct sctp_outq *q)
q
->
error
=
0
;
/* 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
);
}
}
/* 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)
break
;
};
}
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
);
}
...
...
@@ -650,10 +657,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
__u16
sport
=
asoc
->
base
.
bind_addr
.
port
;
__u16
dport
=
asoc
->
peer
.
port
;
__u32
vtag
=
asoc
->
peer
.
i
.
init_tag
;
struct
sk_buff_head
*
queue
;
struct
sctp_transport
*
transport
=
NULL
;
struct
sctp_transport
*
new_transport
;
struct
sctp_chunk
*
chunk
;
struct
sctp_chunk
*
chunk
,
*
tmp
;
sctp_xmit_t
status
;
int
error
=
0
;
int
start_timer
=
0
;
...
...
@@ -675,8 +681,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
* ...
*/
queue
=
&
q
->
control
;
while
((
chunk
=
(
struct
sctp_chunk
*
)
skb_dequeue
(
queue
))
!=
NULL
)
{
list_for_each_entry_safe
(
chunk
,
tmp
,
&
q
->
control_chunk_list
,
list
)
{
list_del_init
(
&
chunk
->
list
);
/* Pick the right transport to use. */
new_transport
=
chunk
->
transport
;
...
...
@@ -814,8 +821,6 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
/* Finally, transmit new packets. */
start_timer
=
0
;
queue
=
&
q
->
out
;
while
((
chunk
=
sctp_outq_dequeue_data
(
q
))
!=
NULL
)
{
/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
* stream identifier.
...
...
@@ -1149,8 +1154,9 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
/* See if all chunks are acked.
* Make sure the empty queue handler will get run later.
*/
q
->
empty
=
skb_queue_empty
(
&
q
->
out
)
&&
skb_queue_empty
(
&
q
->
control
)
&&
list_empty
(
&
q
->
retransmit
);
q
->
empty
=
(
list_empty
(
&
q
->
out_chunk_list
)
&&
list_empty
(
&
q
->
control_chunk_list
)
&&
list_empty
(
&
q
->
retransmit
));
if
(
!
q
->
empty
)
goto
finish
;
...
...
@@ -1679,9 +1685,9 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
if
(
TSN_lte
(
tsn
,
ctsn
))
{
list_del_init
(
lchunk
);
if
(
!
chunk
->
tsn_gap_acked
)
{
chunk
->
transport
->
flight_size
-=
sctp_data_size
(
chunk
);
q
->
outstanding_bytes
-=
sctp_data_size
(
chunk
);
chunk
->
transport
->
flight_size
-=
sctp_data_size
(
chunk
);
q
->
outstanding_bytes
-=
sctp_data_size
(
chunk
);
}
sctp_chunk_free
(
chunk
);
}
else
{
...
...
@@ -1729,7 +1735,7 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
nskips
,
&
ftsn_skip_arr
[
0
]);
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
);
}
}
net/sctp/sm_make_chunk.c
View file @
79af02c2
...
...
@@ -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
);
}
INIT_LIST_HEAD
(
&
retval
->
list
);
retval
->
skb
=
skb
;
retval
->
asoc
=
(
struct
sctp_association
*
)
asoc
;
retval
->
resent
=
0
;
...
...
@@ -1116,8 +1117,7 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk)
/* Possibly, free the chunk. */
void
sctp_chunk_free
(
struct
sctp_chunk
*
chunk
)
{
/* Make sure that we are not on any list. */
skb_unlink
((
struct
sk_buff
*
)
chunk
);
BUG_ON
(
!
list_empty
(
&
chunk
->
list
));
list_del_init
(
&
chunk
->
transmitted_list
);
/* Release our reference on the message tracker. */
...
...
@@ -2739,8 +2739,12 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
asoc
->
addip_last_asconf
=
NULL
;
/* Send the next asconf chunk from the addip chunk queue. */
asconf
=
(
struct
sctp_chunk
*
)
__skb_dequeue
(
&
asoc
->
addip_chunks
);
if
(
asconf
)
{
if
(
!
list_empty
(
&
asoc
->
addip_chunk_list
))
{
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. */
sctp_chunk_hold
(
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,
* transmission.
*/
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
;
}
...
...
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