aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2013-11-21 21:32:11 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-23 17:46:19 -0500
commitb8ee93ba80b5a0b6c3c06b65c34dd1276f16c047 (patch)
tree11f6e9c6ef60f51391b9a4564c0f285fab23da97 /net
parentcc5c00bbb44c5d68b883aa5cb9d01514a2525d94 (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.c26
-rw-r--r--net/ipv6/tcpv6_offload.c27
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 }
290flush: 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
308skip_csum: 302skip_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 }
53flush: 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
72skip_csum: 65skip_csum: