aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2009-02-13 03:33:42 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-16 03:03:10 -0500
commit4458f04c02a46c679a90ef71f866a415c192deb4 (patch)
treeb08aa476ab4c525ab3cb33cea6114cb262cb2941
parent06e868066e3b5828383eb40ff4d1c0029100b0b5 (diff)
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>
-rw-r--r--include/linux/sctp.h2
-rw-r--r--include/net/sctp/checksum.h14
-rw-r--r--net/sctp/input.c11
-rw-r--r--net/sctp/output.c14
4 files changed, 20 insertions, 21 deletions
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index bd50b371ffaa..c2731bfe04d8 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -60,7 +60,7 @@ typedef struct sctphdr {
60 __be16 source; 60 __be16 source;
61 __be16 dest; 61 __be16 dest;
62 __be32 vtag; 62 __be32 vtag;
63 __be32 checksum; 63 __le32 checksum;
64} __attribute__((packed)) sctp_sctphdr_t; 64} __attribute__((packed)) sctp_sctphdr_t;
65 65
66#ifdef __KERNEL__ 66#ifdef __KERNEL__
diff --git a/include/net/sctp/checksum.h b/include/net/sctp/checksum.h
index 2fec3c366e81..befc8d2a1b9f 100644
--- a/include/net/sctp/checksum.h
+++ b/include/net/sctp/checksum.h
@@ -46,14 +46,14 @@
46#include <net/sctp/sctp.h> 46#include <net/sctp/sctp.h>
47#include <linux/crc32c.h> 47#include <linux/crc32c.h>
48 48
49static inline __be32 sctp_crc32c(__be32 crc, u8 *buffer, u16 length) 49static 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
54static inline __be32 sctp_start_cksum(__u8 *buffer, __u16 length) 54static inline __u32 sctp_start_cksum(__u8 *buffer, __u16 length)
55{ 55{
56 __be32 crc = ~cpu_to_be32(0); 56 __u32 crc = ~(__u32)0;
57 __u8 zero[sizeof(__u32)] = {0}; 57 __u8 zero[sizeof(__u32)] = {0};
58 58
59 /* Optimize this routine to be SCTP specific, knowing how 59 /* Optimize this routine to be SCTP specific, knowing how
@@ -72,12 +72,12 @@ static inline __be32 sctp_start_cksum(__u8 *buffer, __u16 length)
72 return crc; 72 return crc;
73} 73}
74 74
75static inline __be32 sctp_update_cksum(__u8 *buffer, __u16 length, __be32 crc32) 75static inline __u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32)
76{ 76{
77 return sctp_crc32c(crc32, buffer, length); 77 return sctp_crc32c(crc32, buffer, length);
78} 78}
79 79
80static inline __be32 sctp_end_cksum(__be32 crc32) 80static 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}
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 693fd0804810..d2e98803ffe3 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -83,14 +83,15 @@ static inline int sctp_rcv_checksum(struct sk_buff *skb)
83{ 83{
84 struct sk_buff *list = skb_shinfo(skb)->frag_list; 84 struct sk_buff *list = skb_shinfo(skb)->frag_list;
85 struct sctphdr *sh = sctp_hdr(skb); 85 struct sctphdr *sh = sctp_hdr(skb);
86 __be32 cmp = sh->checksum; 86 __le32 cmp = sh->checksum;
87 __be32 val = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); 87 __le32 val;
88 __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
88 89
89 for (; list; list = list->next) 90 for (; list; list = list->next)
90 val = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), 91 tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list),
91 val); 92 tmp);
92 93
93 val = sctp_end_cksum(val); 94 val = sctp_end_cksum(tmp);
94 95
95 if (val != cmp) { 96 if (val != cmp) {
96 /* CRC failure, dump it. */ 97 /* CRC failure, dump it. */
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 2d65b7a7330b..07d58903a746 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -367,7 +367,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
367 struct sctp_transport *tp = packet->transport; 367 struct sctp_transport *tp = packet->transport;
368 struct sctp_association *asoc = tp->asoc; 368 struct sctp_association *asoc = tp->asoc;
369 struct sctphdr *sh; 369 struct sctphdr *sh;
370 __be32 crc32 = cpu_to_be32(0);
371 struct sk_buff *nskb; 370 struct sk_buff *nskb;
372 struct sctp_chunk *chunk, *tmp; 371 struct sctp_chunk *chunk, *tmp;
373 struct sock *sk; 372 struct sock *sk;
@@ -532,16 +531,15 @@ int sctp_packet_transmit(struct sctp_packet *packet)
532 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. 531 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
533 */ 532 */
534 if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) { 533 if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) {
535 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); 534 __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
536 crc32 = sctp_end_cksum(crc32); 535
536 /* 3) Put the resultant value into the checksum field in the
537 * common header, and leave the rest of the bits unchanged.
538 */
539 sh->checksum = sctp_end_cksum(crc32);
537 } else 540 } else
538 nskb->ip_summed = CHECKSUM_UNNECESSARY; 541 nskb->ip_summed = CHECKSUM_UNNECESSARY;
539 542
540 /* 3) Put the resultant value into the checksum field in the
541 * common header, and leave the rest of the bits unchanged.
542 */
543 sh->checksum = crc32;
544
545 /* IP layer ECN support 543 /* IP layer ECN support
546 * From RFC 2481 544 * From RFC 2481
547 * "The ECN-Capable Transport (ECT) bit would be set by the 545 * "The ECN-Capable Transport (ECT) bit would be set by the