Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sctp: Clean up sctp checksumming code

The sctp crc32c checksum is always generated in little endian.
So, we clean up the code to treat it as little endian and remove
all the __force casts.

Suggested by Herbert Xu.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Vlad Yasevich and committed by
David S. Miller
4458f04c 06e86806

+20 -21
+1 -1
include/linux/sctp.h
··· 60 60 __be16 source; 61 61 __be16 dest; 62 62 __be32 vtag; 63 - __be32 checksum; 63 + __le32 checksum; 64 64 } __attribute__((packed)) sctp_sctphdr_t; 65 65 66 66 #ifdef __KERNEL__
+7 -7
include/net/sctp/checksum.h
··· 46 46 #include <net/sctp/sctp.h> 47 47 #include <linux/crc32c.h> 48 48 49 - static inline __be32 sctp_crc32c(__be32 crc, u8 *buffer, u16 length) 49 + static inline __u32 sctp_crc32c(__u32 crc, u8 *buffer, u16 length) 50 50 { 51 - return (__force __be32)crc32c((__force u32)crc, buffer, length); 51 + return crc32c(crc, buffer, length); 52 52 } 53 53 54 - static inline __be32 sctp_start_cksum(__u8 *buffer, __u16 length) 54 + static inline __u32 sctp_start_cksum(__u8 *buffer, __u16 length) 55 55 { 56 - __be32 crc = ~cpu_to_be32(0); 56 + __u32 crc = ~(__u32)0; 57 57 __u8 zero[sizeof(__u32)] = {0}; 58 58 59 59 /* Optimize this routine to be SCTP specific, knowing how ··· 72 72 return crc; 73 73 } 74 74 75 - static inline __be32 sctp_update_cksum(__u8 *buffer, __u16 length, __be32 crc32) 75 + static inline __u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32) 76 76 { 77 77 return sctp_crc32c(crc32, buffer, length); 78 78 } 79 79 80 - static inline __be32 sctp_end_cksum(__be32 crc32) 80 + static inline __le32 sctp_end_cksum(__be32 crc32) 81 81 { 82 - return (__force __be32)~cpu_to_le32((__force u32)crc32); 82 + return cpu_to_le32(~crc32); 83 83 }
+6 -5
net/sctp/input.c
··· 83 83 { 84 84 struct sk_buff *list = skb_shinfo(skb)->frag_list; 85 85 struct sctphdr *sh = sctp_hdr(skb); 86 - __be32 cmp = sh->checksum; 87 - __be32 val = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); 86 + __le32 cmp = sh->checksum; 87 + __le32 val; 88 + __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); 88 89 89 90 for (; list; list = list->next) 90 - val = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), 91 - val); 91 + tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), 92 + tmp); 92 93 93 - val = sctp_end_cksum(val); 94 + val = sctp_end_cksum(tmp); 94 95 95 96 if (val != cmp) { 96 97 /* CRC failure, dump it. */
+6 -8
net/sctp/output.c
··· 367 367 struct sctp_transport *tp = packet->transport; 368 368 struct sctp_association *asoc = tp->asoc; 369 369 struct sctphdr *sh; 370 - __be32 crc32 = cpu_to_be32(0); 371 370 struct sk_buff *nskb; 372 371 struct sctp_chunk *chunk, *tmp; 373 372 struct sock *sk; ··· 531 532 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. 532 533 */ 533 534 if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) { 534 - crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); 535 - crc32 = sctp_end_cksum(crc32); 535 + __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); 536 + 537 + /* 3) Put the resultant value into the checksum field in the 538 + * common header, and leave the rest of the bits unchanged. 539 + */ 540 + sh->checksum = sctp_end_cksum(crc32); 536 541 } else 537 542 nskb->ip_summed = CHECKSUM_UNNECESSARY; 538 - 539 - /* 3) Put the resultant value into the checksum field in the 540 - * common header, and leave the rest of the bits unchanged. 541 - */ 542 - sh->checksum = crc32; 543 543 544 544 /* IP layer ECN support 545 545 * From RFC 2481