diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2013-11-21 21:32:11 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-11-23 17:46:19 -0500 |
commit | b8ee93ba80b5a0b6c3c06b65c34dd1276f16c047 (patch) | |
tree | 11f6e9c6ef60f51391b9a4564c0f285fab23da97 /net | |
parent | cc5c00bbb44c5d68b883aa5cb9d01514a2525d94 (diff) |
gro: Clean up tcpX_gro_receive checksum verification
This patch simplifies the checksum verification in tcpX_gro_receive
by reusing the CHECKSUM_COMPLETE code for CHECKSUM_NONE. All it
does for CHECKSUM_NONE is compute the partial checksum and then
treat it as if it came from the hardware (CHECKSUM_COMPLETE).
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Cheers,
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/tcp_offload.c | 26 | ||||
-rw-r--r-- | net/ipv6/tcpv6_offload.c | 27 |
2 files changed, 20 insertions, 33 deletions
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c index 55aeec930140..05606353c7e7 100644 --- a/net/ipv4/tcp_offload.c +++ b/net/ipv4/tcp_offload.c | |||
@@ -274,35 +274,29 @@ static struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff * | |||
274 | { | 274 | { |
275 | const struct iphdr *iph = skb_gro_network_header(skb); | 275 | const struct iphdr *iph = skb_gro_network_header(skb); |
276 | __wsum wsum; | 276 | __wsum wsum; |
277 | __sum16 sum; | ||
278 | 277 | ||
279 | /* Don't bother verifying checksum if we're going to flush anyway. */ | 278 | /* Don't bother verifying checksum if we're going to flush anyway. */ |
280 | if (NAPI_GRO_CB(skb)->flush) | 279 | if (NAPI_GRO_CB(skb)->flush) |
281 | goto skip_csum; | 280 | goto skip_csum; |
282 | 281 | ||
282 | wsum = skb->csum; | ||
283 | |||
283 | switch (skb->ip_summed) { | 284 | switch (skb->ip_summed) { |
285 | case CHECKSUM_NONE: | ||
286 | wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb), | ||
287 | 0); | ||
288 | |||
289 | /* fall through */ | ||
290 | |||
284 | case CHECKSUM_COMPLETE: | 291 | case CHECKSUM_COMPLETE: |
285 | if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr, | 292 | if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr, |
286 | skb->csum)) { | 293 | wsum)) { |
287 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 294 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
288 | break; | 295 | break; |
289 | } | 296 | } |
290 | flush: | 297 | |
291 | NAPI_GRO_CB(skb)->flush = 1; | 298 | NAPI_GRO_CB(skb)->flush = 1; |
292 | return NULL; | 299 | return NULL; |
293 | |||
294 | case CHECKSUM_NONE: | ||
295 | wsum = csum_tcpudp_nofold(iph->saddr, iph->daddr, | ||
296 | skb_gro_len(skb), IPPROTO_TCP, 0); | ||
297 | sum = csum_fold(skb_checksum(skb, | ||
298 | skb_gro_offset(skb), | ||
299 | skb_gro_len(skb), | ||
300 | wsum)); | ||
301 | if (sum) | ||
302 | goto flush; | ||
303 | |||
304 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
305 | break; | ||
306 | } | 300 | } |
307 | 301 | ||
308 | skip_csum: | 302 | skip_csum: |
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c index 71923d14127a..6d18157dc32c 100644 --- a/net/ipv6/tcpv6_offload.c +++ b/net/ipv6/tcpv6_offload.c | |||
@@ -37,36 +37,29 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, | |||
37 | { | 37 | { |
38 | const struct ipv6hdr *iph = skb_gro_network_header(skb); | 38 | const struct ipv6hdr *iph = skb_gro_network_header(skb); |
39 | __wsum wsum; | 39 | __wsum wsum; |
40 | __sum16 sum; | ||
41 | 40 | ||
42 | /* Don't bother verifying checksum if we're going to flush anyway. */ | 41 | /* Don't bother verifying checksum if we're going to flush anyway. */ |
43 | if (NAPI_GRO_CB(skb)->flush) | 42 | if (NAPI_GRO_CB(skb)->flush) |
44 | goto skip_csum; | 43 | goto skip_csum; |
45 | 44 | ||
45 | wsum = skb->csum; | ||
46 | |||
46 | switch (skb->ip_summed) { | 47 | switch (skb->ip_summed) { |
48 | case CHECKSUM_NONE: | ||
49 | wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb), | ||
50 | wsum); | ||
51 | |||
52 | /* fall through */ | ||
53 | |||
47 | case CHECKSUM_COMPLETE: | 54 | case CHECKSUM_COMPLETE: |
48 | if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr, | 55 | if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr, |
49 | skb->csum)) { | 56 | wsum)) { |
50 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 57 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
51 | break; | 58 | break; |
52 | } | 59 | } |
53 | flush: | 60 | |
54 | NAPI_GRO_CB(skb)->flush = 1; | 61 | NAPI_GRO_CB(skb)->flush = 1; |
55 | return NULL; | 62 | return NULL; |
56 | |||
57 | case CHECKSUM_NONE: | ||
58 | wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr, | ||
59 | skb_gro_len(skb), | ||
60 | IPPROTO_TCP, 0)); | ||
61 | sum = csum_fold(skb_checksum(skb, | ||
62 | skb_gro_offset(skb), | ||
63 | skb_gro_len(skb), | ||
64 | wsum)); | ||
65 | if (sum) | ||
66 | goto flush; | ||
67 | |||
68 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
69 | break; | ||
70 | } | 63 | } |
71 | 64 | ||
72 | skip_csum: | 65 | skip_csum: |