aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/output.c')
-rw-r--r--net/sctp/output.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 437cba7260a4..cdc5a3936766 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -295,14 +295,14 @@ int sctp_packet_transmit(struct sctp_packet *packet)
295 struct sctp_transport *tp = packet->transport; 295 struct sctp_transport *tp = packet->transport;
296 struct sctp_association *asoc = tp->asoc; 296 struct sctp_association *asoc = tp->asoc;
297 struct sctphdr *sh; 297 struct sctphdr *sh;
298 __u32 crc32; 298 __u32 crc32 = 0;
299 struct sk_buff *nskb; 299 struct sk_buff *nskb;
300 struct sctp_chunk *chunk, *tmp; 300 struct sctp_chunk *chunk, *tmp;
301 struct sock *sk; 301 struct sock *sk;
302 int err = 0; 302 int err = 0;
303 int padding; /* How much padding do we need? */ 303 int padding; /* How much padding do we need? */
304 __u8 has_data = 0; 304 __u8 has_data = 0;
305 struct dst_entry *dst; 305 struct dst_entry *dst = tp->dst;
306 306
307 SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); 307 SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);
308 308
@@ -327,6 +327,19 @@ int sctp_packet_transmit(struct sctp_packet *packet)
327 */ 327 */
328 skb_set_owner_w(nskb, sk); 328 skb_set_owner_w(nskb, sk);
329 329
330 /* The 'obsolete' field of dst is set to 2 when a dst is freed. */
331 if (!dst || (dst->obsolete > 1)) {
332 dst_release(dst);
333 sctp_transport_route(tp, NULL, sctp_sk(sk));
334 if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) {
335 sctp_assoc_sync_pmtu(asoc);
336 }
337 }
338 nskb->dst = dst_clone(tp->dst);
339 if (!nskb->dst)
340 goto no_route;
341 dst = nskb->dst;
342
330 /* Build the SCTP header. */ 343 /* Build the SCTP header. */
331 sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); 344 sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
332 sh->source = htons(packet->source_port); 345 sh->source = htons(packet->source_port);
@@ -350,7 +363,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
350 * Note: Adler-32 is no longer applicable, as has been replaced 363 * Note: Adler-32 is no longer applicable, as has been replaced
351 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. 364 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
352 */ 365 */
353 crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr)); 366 if (!(dst->dev->features & NETIF_F_NO_CSUM))
367 crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr));
354 368
355 /** 369 /**
356 * 6.10 Bundling 370 * 6.10 Bundling
@@ -402,9 +416,14 @@ int sctp_packet_transmit(struct sctp_packet *packet)
402 if (padding) 416 if (padding)
403 memset(skb_put(chunk->skb, padding), 0, padding); 417 memset(skb_put(chunk->skb, padding), 0, padding);
404 418
405 crc32 = sctp_update_copy_cksum(skb_put(nskb, chunk->skb->len), 419 if (dst->dev->features & NETIF_F_NO_CSUM)
406 chunk->skb->data, 420 memcpy(skb_put(nskb, chunk->skb->len),
407 chunk->skb->len, crc32); 421 chunk->skb->data, chunk->skb->len);
422 else
423 crc32 = sctp_update_copy_cksum(skb_put(nskb,
424 chunk->skb->len),
425 chunk->skb->data,
426 chunk->skb->len, crc32);
408 427
409 SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n", 428 SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n",
410 "*** Chunk", chunk, 429 "*** Chunk", chunk,
@@ -427,7 +446,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
427 } 446 }
428 447
429 /* Perform final transformation on checksum. */ 448 /* Perform final transformation on checksum. */
430 crc32 = sctp_end_cksum(crc32); 449 if (!(dst->dev->features & NETIF_F_NO_CSUM))
450 crc32 = sctp_end_cksum(crc32);
431 451
432 /* 3) Put the resultant value into the checksum field in the 452 /* 3) Put the resultant value into the checksum field in the
433 * common header, and leave the rest of the bits unchanged. 453 * common header, and leave the rest of the bits unchanged.
@@ -477,20 +497,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
477 } 497 }
478 } 498 }
479 499
480 dst = tp->dst;
481 /* The 'obsolete' field of dst is set to 2 when a dst is freed. */
482 if (!dst || (dst->obsolete > 1)) {
483 dst_release(dst);
484 sctp_transport_route(tp, NULL, sctp_sk(sk));
485 if (asoc->param_flags & SPP_PMTUD_ENABLE) {
486 sctp_assoc_sync_pmtu(asoc);
487 }
488 }
489
490 nskb->dst = dst_clone(tp->dst);
491 if (!nskb->dst)
492 goto no_route;
493
494 SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n", 500 SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
495 nskb->len); 501 nskb->len);
496 502