net/sctp: Refactor SCTP skb checksum computation
authorJoe Stringer <joe@wand.net.nz>
Thu, 25 Jul 2013 01:52:05 +0000 (10:52 +0900)
committerDavid S. Miller <davem@davemloft.net>
Sun, 28 Jul 2013 03:07:15 +0000 (20:07 -0700)
This patch consolidates the SCTP checksum calculation code from various
places to a single new function, sctp_compute_cksum(skb, offset).

Signed-off-by: Joe Stringer <joe@wand.net.nz>
Reviewed-by: Julian Anastasov <ja@ssi.bg>
Acked-by: Simon Horman <horms@verge.net.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sctp/checksum.h
net/netfilter/ipvs/ip_vs_proto_sctp.c
net/netfilter/nf_nat_proto_sctp.c
net/sctp/input.c

index 78b88aa8c8103458581f280e2e6cc7e292497d9d..483e6303458d41d46f7a059a7762af6fab1d0bfd 100644 (file)
@@ -85,4 +85,19 @@ static inline __le32 sctp_end_cksum(__u32 crc32)
        return cpu_to_le32(~crc32);
 }
 
+/* Calculate the CRC32C checksum of an SCTP packet.  */
+static inline __le32 sctp_compute_cksum(const struct sk_buff *skb,
+                                       unsigned int offset)
+{
+       const struct sk_buff *iter;
+
+       __u32 crc32 = sctp_start_cksum(skb->data + offset,
+                                      skb_headlen(skb) - offset);
+       skb_walk_frags(skb, iter)
+               crc32 = sctp_update_cksum((__u8 *) iter->data,
+                                         skb_headlen(iter), crc32);
+
+       return sctp_end_cksum(crc32);
+}
+
 #endif /* __sctp_checksum_h__ */
index 3c0da8728036346a6a9ba235821779b49931b311..23e596e438b3fb4e51a97782c4cf00ad7d33af68 100644 (file)
@@ -66,15 +66,7 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
 static void sctp_nat_csum(struct sk_buff *skb, sctp_sctphdr_t *sctph,
                          unsigned int sctphoff)
 {
-       __u32 crc32;
-       struct sk_buff *iter;
-
-       crc32 = sctp_start_cksum((__u8 *)sctph, skb_headlen(skb) - sctphoff);
-       skb_walk_frags(skb, iter)
-               crc32 = sctp_update_cksum((u8 *) iter->data,
-                                         skb_headlen(iter), crc32);
-       sctph->checksum = sctp_end_cksum(crc32);
-
+       sctph->checksum = sctp_compute_cksum(skb, sctphoff);
        skb->ip_summed = CHECKSUM_UNNECESSARY;
 }
 
@@ -151,10 +143,7 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
 {
        unsigned int sctphoff;
        struct sctphdr *sh, _sctph;
-       struct sk_buff *iter;
-       __le32 cmp;
-       __le32 val;
-       __u32 tmp;
+       __le32 cmp, val;
 
 #ifdef CONFIG_IP_VS_IPV6
        if (af == AF_INET6)
@@ -168,13 +157,7 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
                return 0;
 
        cmp = sh->checksum;
-
-       tmp = sctp_start_cksum((__u8 *) sh, skb_headlen(skb));
-       skb_walk_frags(skb, iter)
-               tmp = sctp_update_cksum((__u8 *) iter->data,
-                                       skb_headlen(iter), tmp);
-
-       val = sctp_end_cksum(tmp);
+       val = sctp_compute_cksum(skb, sctphoff);
 
        if (val != cmp) {
                /* CRC failure, dump it. */
index 396e55d46f90c77ea25a88cc1e94decc76f81050..754536f2c67488acd4345cdcec3740916ab24fea 100644 (file)
@@ -34,9 +34,7 @@ sctp_manip_pkt(struct sk_buff *skb,
               const struct nf_conntrack_tuple *tuple,
               enum nf_nat_manip_type maniptype)
 {
-       struct sk_buff *frag;
        sctp_sctphdr_t *hdr;
-       __u32 crc32;
 
        if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
                return false;
@@ -51,11 +49,7 @@ sctp_manip_pkt(struct sk_buff *skb,
                hdr->dest = tuple->dst.u.sctp.port;
        }
 
-       crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff);
-       skb_walk_frags(skb, frag)
-               crc32 = sctp_update_cksum((u8 *)frag->data, skb_headlen(frag),
-                                         crc32);
-       hdr->checksum = sctp_end_cksum(crc32);
+       hdr->checksum = sctp_compute_cksum(skb, hdroff);
 
        return true;
 }
index 7993495a4c0f13f3111349c60ae05226c7c573b8..fa91aff0238874ae21682c87abc27a640cf19401 100644 (file)
@@ -87,15 +87,7 @@ static inline int sctp_rcv_checksum(struct net *net, struct sk_buff *skb)
 {
        struct sctphdr *sh = sctp_hdr(skb);
        __le32 cmp = sh->checksum;
-       struct sk_buff *list;
-       __le32 val;
-       __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
-
-       skb_walk_frags(skb, list)
-               tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list),
-                                       tmp);
-
-       val = sctp_end_cksum(tmp);
+       __le32 val = sctp_compute_cksum(skb, 0);
 
        if (val != cmp) {
                /* CRC failure, dump it. */