diff options
author | Eric Dumazet <edumazet@google.com> | 2012-09-26 22:14:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-10-01 17:00:27 -0400 |
commit | 861b650101eb0c627d171eb18de81dddb93d395e (patch) | |
tree | 07c0b874476d6d82f8618c071402e742b1705b66 /net/ipv4/tcp_ipv4.c | |
parent | 64c6d08e6490fb18cea09bb03686c149946bd818 (diff) |
tcp: gro: add checksuming helpers
skb with CHECKSUM_NONE cant currently be handled by GRO, and
we notice this deep in GRO stack in tcp[46]_gro_receive()
But there are cases where GRO can be a benefit, even with a lack
of checksums.
This preliminary work is needed to add GRO support
to tunnels.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 385eb79cf6aa..75735c9a6a9d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -2803,6 +2803,8 @@ void tcp4_proc_exit(void) | |||
2803 | struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb) | 2803 | struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb) |
2804 | { | 2804 | { |
2805 | const struct iphdr *iph = skb_gro_network_header(skb); | 2805 | const struct iphdr *iph = skb_gro_network_header(skb); |
2806 | __wsum wsum; | ||
2807 | __sum16 sum; | ||
2806 | 2808 | ||
2807 | switch (skb->ip_summed) { | 2809 | switch (skb->ip_summed) { |
2808 | case CHECKSUM_COMPLETE: | 2810 | case CHECKSUM_COMPLETE: |
@@ -2811,11 +2813,22 @@ struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2811 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 2813 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
2812 | break; | 2814 | break; |
2813 | } | 2815 | } |
2814 | 2816 | flush: | |
2815 | /* fall through */ | ||
2816 | case CHECKSUM_NONE: | ||
2817 | NAPI_GRO_CB(skb)->flush = 1; | 2817 | NAPI_GRO_CB(skb)->flush = 1; |
2818 | return NULL; | 2818 | return NULL; |
2819 | |||
2820 | case CHECKSUM_NONE: | ||
2821 | wsum = csum_tcpudp_nofold(iph->saddr, iph->daddr, | ||
2822 | skb_gro_len(skb), IPPROTO_TCP, 0); | ||
2823 | sum = csum_fold(skb_checksum(skb, | ||
2824 | skb_gro_offset(skb), | ||
2825 | skb_gro_len(skb), | ||
2826 | wsum)); | ||
2827 | if (sum) | ||
2828 | goto flush; | ||
2829 | |||
2830 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
2831 | break; | ||
2819 | } | 2832 | } |
2820 | 2833 | ||
2821 | return tcp_gro_receive(head, skb); | 2834 | return tcp_gro_receive(head, skb); |