|
@@ -412,6 +412,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
|
|
|
|
|
|
/* Build the SCTP header. */
|
|
|
sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
|
|
|
+ skb_reset_transport_header(nskb);
|
|
|
sh->source = htons(packet->source_port);
|
|
|
sh->dest = htons(packet->destination_port);
|
|
|
|
|
@@ -527,15 +528,25 @@ int sctp_packet_transmit(struct sctp_packet *packet)
|
|
|
* Note: Adler-32 is no longer applicable, as has been replaced
|
|
|
* by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
|
|
|
*/
|
|
|
- if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) {
|
|
|
+ if (!sctp_checksum_disable &&
|
|
|
+ !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) {
|
|
|
__u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
|
|
|
|
|
|
/* 3) Put the resultant value into the checksum field in the
|
|
|
* common header, and leave the rest of the bits unchanged.
|
|
|
*/
|
|
|
sh->checksum = sctp_end_cksum(crc32);
|
|
|
- } else
|
|
|
- nskb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
|
+ } else {
|
|
|
+ if (dst->dev->features & NETIF_F_SCTP_CSUM) {
|
|
|
+ /* no need to seed psuedo checksum for SCTP */
|
|
|
+ nskb->ip_summed = CHECKSUM_PARTIAL;
|
|
|
+ nskb->csum_start = (skb_transport_header(nskb) -
|
|
|
+ nskb->head);
|
|
|
+ nskb->csum_offset = offsetof(struct sctphdr, checksum);
|
|
|
+ } else {
|
|
|
+ nskb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/* IP layer ECN support
|
|
|
* From RFC 2481
|