diff options
-rw-r--r-- | net/sctp/output.c | 79 |
1 files changed, 52 insertions, 27 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c index 6ae47acaaec6..539f35d07f4e 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -64,6 +64,8 @@ | |||
64 | #include <net/sctp/checksum.h> | 64 | #include <net/sctp/checksum.h> |
65 | 65 | ||
66 | /* Forward declarations for private helpers. */ | 66 | /* Forward declarations for private helpers. */ |
67 | static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet, | ||
68 | struct sctp_chunk *chunk); | ||
67 | static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, | 69 | static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, |
68 | struct sctp_chunk *chunk); | 70 | struct sctp_chunk *chunk); |
69 | static void sctp_packet_append_data(struct sctp_packet *packet, | 71 | static void sctp_packet_append_data(struct sctp_packet *packet, |
@@ -224,7 +226,10 @@ static sctp_xmit_t sctp_packet_bundle_auth(struct sctp_packet *pkt, | |||
224 | if (!auth) | 226 | if (!auth) |
225 | return retval; | 227 | return retval; |
226 | 228 | ||
227 | retval = sctp_packet_append_chunk(pkt, auth); | 229 | retval = __sctp_packet_append_chunk(pkt, auth); |
230 | |||
231 | if (retval != SCTP_XMIT_OK) | ||
232 | sctp_chunk_free(auth); | ||
228 | 233 | ||
229 | return retval; | 234 | return retval; |
230 | } | 235 | } |
@@ -256,48 +261,31 @@ static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt, | |||
256 | asoc->a_rwnd = asoc->rwnd; | 261 | asoc->a_rwnd = asoc->rwnd; |
257 | sack = sctp_make_sack(asoc); | 262 | sack = sctp_make_sack(asoc); |
258 | if (sack) { | 263 | if (sack) { |
259 | retval = sctp_packet_append_chunk(pkt, sack); | 264 | retval = __sctp_packet_append_chunk(pkt, sack); |
265 | if (retval != SCTP_XMIT_OK) { | ||
266 | sctp_chunk_free(sack); | ||
267 | goto out; | ||
268 | } | ||
260 | asoc->peer.sack_needed = 0; | 269 | asoc->peer.sack_needed = 0; |
261 | if (del_timer(timer)) | 270 | if (del_timer(timer)) |
262 | sctp_association_put(asoc); | 271 | sctp_association_put(asoc); |
263 | } | 272 | } |
264 | } | 273 | } |
265 | } | 274 | } |
275 | out: | ||
266 | return retval; | 276 | return retval; |
267 | } | 277 | } |
268 | 278 | ||
279 | |||
269 | /* Append a chunk to the offered packet reporting back any inability to do | 280 | /* Append a chunk to the offered packet reporting back any inability to do |
270 | * so. | 281 | * so. |
271 | */ | 282 | */ |
272 | sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, | 283 | static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet, |
273 | struct sctp_chunk *chunk) | 284 | struct sctp_chunk *chunk) |
274 | { | 285 | { |
275 | sctp_xmit_t retval = SCTP_XMIT_OK; | 286 | sctp_xmit_t retval = SCTP_XMIT_OK; |
276 | __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length)); | 287 | __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length)); |
277 | 288 | ||
278 | SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet, | ||
279 | chunk); | ||
280 | |||
281 | /* Data chunks are special. Before seeing what else we can | ||
282 | * bundle into this packet, check to see if we are allowed to | ||
283 | * send this DATA. | ||
284 | */ | ||
285 | if (sctp_chunk_is_data(chunk)) { | ||
286 | retval = sctp_packet_can_append_data(packet, chunk); | ||
287 | if (retval != SCTP_XMIT_OK) | ||
288 | goto finish; | ||
289 | } | ||
290 | |||
291 | /* Try to bundle AUTH chunk */ | ||
292 | retval = sctp_packet_bundle_auth(packet, chunk); | ||
293 | if (retval != SCTP_XMIT_OK) | ||
294 | goto finish; | ||
295 | |||
296 | /* Try to bundle SACK chunk */ | ||
297 | retval = sctp_packet_bundle_sack(packet, chunk); | ||
298 | if (retval != SCTP_XMIT_OK) | ||
299 | goto finish; | ||
300 | |||
301 | /* Check to see if this chunk will fit into the packet */ | 289 | /* Check to see if this chunk will fit into the packet */ |
302 | retval = sctp_packet_will_fit(packet, chunk, chunk_len); | 290 | retval = sctp_packet_will_fit(packet, chunk, chunk_len); |
303 | if (retval != SCTP_XMIT_OK) | 291 | if (retval != SCTP_XMIT_OK) |
@@ -339,6 +327,43 @@ finish: | |||
339 | return retval; | 327 | return retval; |
340 | } | 328 | } |
341 | 329 | ||
330 | /* Append a chunk to the offered packet reporting back any inability to do | ||
331 | * so. | ||
332 | */ | ||
333 | sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, | ||
334 | struct sctp_chunk *chunk) | ||
335 | { | ||
336 | sctp_xmit_t retval = SCTP_XMIT_OK; | ||
337 | |||
338 | SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet, | ||
339 | chunk); | ||
340 | |||
341 | /* Data chunks are special. Before seeing what else we can | ||
342 | * bundle into this packet, check to see if we are allowed to | ||
343 | * send this DATA. | ||
344 | */ | ||
345 | if (sctp_chunk_is_data(chunk)) { | ||
346 | retval = sctp_packet_can_append_data(packet, chunk); | ||
347 | if (retval != SCTP_XMIT_OK) | ||
348 | goto finish; | ||
349 | } | ||
350 | |||
351 | /* Try to bundle AUTH chunk */ | ||
352 | retval = sctp_packet_bundle_auth(packet, chunk); | ||
353 | if (retval != SCTP_XMIT_OK) | ||
354 | goto finish; | ||
355 | |||
356 | /* Try to bundle SACK chunk */ | ||
357 | retval = sctp_packet_bundle_sack(packet, chunk); | ||
358 | if (retval != SCTP_XMIT_OK) | ||
359 | goto finish; | ||
360 | |||
361 | retval = __sctp_packet_append_chunk(packet, chunk); | ||
362 | |||
363 | finish: | ||
364 | return retval; | ||
365 | } | ||
366 | |||
342 | /* All packets are sent to the network through this function from | 367 | /* All packets are sent to the network through this function from |
343 | * sctp_outq_tail(). | 368 | * sctp_outq_tail(). |
344 | * | 369 | * |