Skip to content

Commit 861b650

Browse files
Eric Dumazetdavem330
authored andcommitted
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>
1 parent 64c6d08 commit 861b650

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

net/ipv4/tcp_ipv4.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2803,6 +2803,8 @@ void tcp4_proc_exit(void)
28032803
struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb)
28042804
{
28052805
const struct iphdr *iph = skb_gro_network_header(skb);
2806+
__wsum wsum;
2807+
__sum16 sum;
28062808

28072809
switch (skb->ip_summed) {
28082810
case CHECKSUM_COMPLETE:
@@ -2811,11 +2813,22 @@ struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb)
28112813
skb->ip_summed = CHECKSUM_UNNECESSARY;
28122814
break;
28132815
}
2814-
2815-
/* fall through */
2816-
case CHECKSUM_NONE:
2816+
flush:
28172817
NAPI_GRO_CB(skb)->flush = 1;
28182818
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;
28192832
}
28202833

28212834
return tcp_gro_receive(head, skb);

net/ipv6/tcp_ipv6.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
763763
struct sk_buff *skb)
764764
{
765765
const struct ipv6hdr *iph = skb_gro_network_header(skb);
766+
__wsum wsum;
767+
__sum16 sum;
766768

767769
switch (skb->ip_summed) {
768770
case CHECKSUM_COMPLETE:
@@ -771,11 +773,23 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
771773
skb->ip_summed = CHECKSUM_UNNECESSARY;
772774
break;
773775
}
774-
775-
/* fall through */
776-
case CHECKSUM_NONE:
776+
flush:
777777
NAPI_GRO_CB(skb)->flush = 1;
778778
return NULL;
779+
780+
case CHECKSUM_NONE:
781+
wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr,
782+
skb_gro_len(skb),
783+
IPPROTO_TCP, 0));
784+
sum = csum_fold(skb_checksum(skb,
785+
skb_gro_offset(skb),
786+
skb_gro_len(skb),
787+
wsum));
788+
if (sum)
789+
goto flush;
790+
791+
skb->ip_summed = CHECKSUM_UNNECESSARY;
792+
break;
779793
}
780794

781795
return tcp_gro_receive(head, skb);

0 commit comments

Comments
 (0)