diff options
Diffstat (limited to 'net/sctp/output.c')
-rw-r--r-- | net/sctp/output.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c index 7d08f522ec84..b76411444515 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -405,13 +405,14 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
405 | sctp_assoc_sync_pmtu(asoc); | 405 | sctp_assoc_sync_pmtu(asoc); |
406 | } | 406 | } |
407 | } | 407 | } |
408 | nskb->dst = dst_clone(tp->dst); | 408 | dst = dst_clone(tp->dst); |
409 | if (!nskb->dst) | 409 | skb_dst_set(nskb, dst); |
410 | if (dst) | ||
410 | goto no_route; | 411 | goto no_route; |
411 | dst = nskb->dst; | ||
412 | 412 | ||
413 | /* Build the SCTP header. */ | 413 | /* Build the SCTP header. */ |
414 | sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); | 414 | sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); |
415 | skb_reset_transport_header(nskb); | ||
415 | sh->source = htons(packet->source_port); | 416 | sh->source = htons(packet->source_port); |
416 | sh->dest = htons(packet->destination_port); | 417 | sh->dest = htons(packet->destination_port); |
417 | 418 | ||
@@ -527,15 +528,25 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
527 | * Note: Adler-32 is no longer applicable, as has been replaced | 528 | * Note: Adler-32 is no longer applicable, as has been replaced |
528 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. | 529 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. |
529 | */ | 530 | */ |
530 | if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) { | 531 | if (!sctp_checksum_disable && |
532 | !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) { | ||
531 | __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); | 533 | __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); |
532 | 534 | ||
533 | /* 3) Put the resultant value into the checksum field in the | 535 | /* 3) Put the resultant value into the checksum field in the |
534 | * common header, and leave the rest of the bits unchanged. | 536 | * common header, and leave the rest of the bits unchanged. |
535 | */ | 537 | */ |
536 | sh->checksum = sctp_end_cksum(crc32); | 538 | sh->checksum = sctp_end_cksum(crc32); |
537 | } else | 539 | } else { |
538 | nskb->ip_summed = CHECKSUM_UNNECESSARY; | 540 | if (dst->dev->features & NETIF_F_SCTP_CSUM) { |
541 | /* no need to seed psuedo checksum for SCTP */ | ||
542 | nskb->ip_summed = CHECKSUM_PARTIAL; | ||
543 | nskb->csum_start = (skb_transport_header(nskb) - | ||
544 | nskb->head); | ||
545 | nskb->csum_offset = offsetof(struct sctphdr, checksum); | ||
546 | } else { | ||
547 | nskb->ip_summed = CHECKSUM_UNNECESSARY; | ||
548 | } | ||
549 | } | ||
539 | 550 | ||
540 | /* IP layer ECN support | 551 | /* IP layer ECN support |
541 | * From RFC 2481 | 552 | * From RFC 2481 |