diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c75acdf71a6f..b029757bea03 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -171,6 +171,36 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk) | |||
171 | sk_mem_charge(sk, chunk->skb->truesize); | 171 | sk_mem_charge(sk, chunk->skb->truesize); |
172 | } | 172 | } |
173 | 173 | ||
174 | static void sctp_clear_owner_w(struct sctp_chunk *chunk) | ||
175 | { | ||
176 | skb_orphan(chunk->skb); | ||
177 | } | ||
178 | |||
179 | static void sctp_for_each_tx_datachunk(struct sctp_association *asoc, | ||
180 | void (*cb)(struct sctp_chunk *)) | ||
181 | |||
182 | { | ||
183 | struct sctp_outq *q = &asoc->outqueue; | ||
184 | struct sctp_transport *t; | ||
185 | struct sctp_chunk *chunk; | ||
186 | |||
187 | list_for_each_entry(t, &asoc->peer.transport_addr_list, transports) | ||
188 | list_for_each_entry(chunk, &t->transmitted, transmitted_list) | ||
189 | cb(chunk); | ||
190 | |||
191 | list_for_each_entry(chunk, &q->retransmit, list) | ||
192 | cb(chunk); | ||
193 | |||
194 | list_for_each_entry(chunk, &q->sacked, list) | ||
195 | cb(chunk); | ||
196 | |||
197 | list_for_each_entry(chunk, &q->abandoned, list) | ||
198 | cb(chunk); | ||
199 | |||
200 | list_for_each_entry(chunk, &q->out_chunk_list, list) | ||
201 | cb(chunk); | ||
202 | } | ||
203 | |||
174 | /* Verify that this is a valid address. */ | 204 | /* Verify that this is a valid address. */ |
175 | static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr, | 205 | static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr, |
176 | int len) | 206 | int len) |
@@ -8379,7 +8409,9 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
8379 | * paths won't try to lock it and then oldsk. | 8409 | * paths won't try to lock it and then oldsk. |
8380 | */ | 8410 | */ |
8381 | lock_sock_nested(newsk, SINGLE_DEPTH_NESTING); | 8411 | lock_sock_nested(newsk, SINGLE_DEPTH_NESTING); |
8412 | sctp_for_each_tx_datachunk(assoc, sctp_clear_owner_w); | ||
8382 | sctp_assoc_migrate(assoc, newsk); | 8413 | sctp_assoc_migrate(assoc, newsk); |
8414 | sctp_for_each_tx_datachunk(assoc, sctp_set_owner_w); | ||
8383 | 8415 | ||
8384 | /* If the association on the newsk is already closed before accept() | 8416 | /* If the association on the newsk is already closed before accept() |
8385 | * is called, set RCV_SHUTDOWN flag. | 8417 | * is called, set RCV_SHUTDOWN flag. |