net/sctp: Refactor SCTP skb checksum computation
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>
This commit is contained in:
parent
e7428e95a0
commit
024ec3deac
4 changed files with 20 additions and 36 deletions
|
@ -85,4 +85,19 @@ static inline __le32 sctp_end_cksum(__u32 crc32)
|
||||||
return cpu_to_le32(~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__ */
|
#endif /* __sctp_checksum_h__ */
|
||||||
|
|
|
@ -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,
|
static void sctp_nat_csum(struct sk_buff *skb, sctp_sctphdr_t *sctph,
|
||||||
unsigned int sctphoff)
|
unsigned int sctphoff)
|
||||||
{
|
{
|
||||||
__u32 crc32;
|
sctph->checksum = sctp_compute_cksum(skb, sctphoff);
|
||||||
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);
|
|
||||||
|
|
||||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
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;
|
unsigned int sctphoff;
|
||||||
struct sctphdr *sh, _sctph;
|
struct sctphdr *sh, _sctph;
|
||||||
struct sk_buff *iter;
|
__le32 cmp, val;
|
||||||
__le32 cmp;
|
|
||||||
__le32 val;
|
|
||||||
__u32 tmp;
|
|
||||||
|
|
||||||
#ifdef CONFIG_IP_VS_IPV6
|
#ifdef CONFIG_IP_VS_IPV6
|
||||||
if (af == AF_INET6)
|
if (af == AF_INET6)
|
||||||
|
@ -168,13 +157,7 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cmp = sh->checksum;
|
cmp = sh->checksum;
|
||||||
|
val = sctp_compute_cksum(skb, sctphoff);
|
||||||
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);
|
|
||||||
|
|
||||||
if (val != cmp) {
|
if (val != cmp) {
|
||||||
/* CRC failure, dump it. */
|
/* CRC failure, dump it. */
|
||||||
|
|
|
@ -34,9 +34,7 @@ sctp_manip_pkt(struct sk_buff *skb,
|
||||||
const struct nf_conntrack_tuple *tuple,
|
const struct nf_conntrack_tuple *tuple,
|
||||||
enum nf_nat_manip_type maniptype)
|
enum nf_nat_manip_type maniptype)
|
||||||
{
|
{
|
||||||
struct sk_buff *frag;
|
|
||||||
sctp_sctphdr_t *hdr;
|
sctp_sctphdr_t *hdr;
|
||||||
__u32 crc32;
|
|
||||||
|
|
||||||
if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
|
if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
|
||||||
return false;
|
return false;
|
||||||
|
@ -51,11 +49,7 @@ sctp_manip_pkt(struct sk_buff *skb,
|
||||||
hdr->dest = tuple->dst.u.sctp.port;
|
hdr->dest = tuple->dst.u.sctp.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff);
|
hdr->checksum = sctp_compute_cksum(skb, hdroff);
|
||||||
skb_walk_frags(skb, frag)
|
|
||||||
crc32 = sctp_update_cksum((u8 *)frag->data, skb_headlen(frag),
|
|
||||||
crc32);
|
|
||||||
hdr->checksum = sctp_end_cksum(crc32);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,15 +87,7 @@ static inline int sctp_rcv_checksum(struct net *net, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct sctphdr *sh = sctp_hdr(skb);
|
struct sctphdr *sh = sctp_hdr(skb);
|
||||||
__le32 cmp = sh->checksum;
|
__le32 cmp = sh->checksum;
|
||||||
struct sk_buff *list;
|
__le32 val = sctp_compute_cksum(skb, 0);
|
||||||
__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);
|
|
||||||
|
|
||||||
if (val != cmp) {
|
if (val != cmp) {
|
||||||
/* CRC failure, dump it. */
|
/* CRC failure, dump it. */
|
||||||
|
|
Loading…
Reference in a new issue