aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-07-08 16:34:56 -0400
committerDavid S. Miller <davem@davemloft.net>2006-07-08 16:34:56 -0400
commita430a43d087545c96542ee64573237919109d370 (patch)
tree653b630298505d5a65e2e094868d83014e4b0dc4 /net/ipv6/tcp_ipv6.c
parent89114afd435a486deb8583e89f490fc274444d18 (diff)
[NET] gso: Fix up GSO packets with broken checksums
Certain subsystems in the stack (e.g., netfilter) can break the partial checksum on GSO packets. Until they're fixed, this patch allows this to work by recomputing the partial checksums through the GSO mechanism. Once they've all been converted to update the partial checksum instead of clearing it, this workaround can be removed. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5bdcb9002cf7..923989d0520d 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -552,6 +552,24 @@ static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
552 } 552 }
553} 553}
554 554
555static int tcp_v6_gso_send_check(struct sk_buff *skb)
556{
557 struct ipv6hdr *ipv6h;
558 struct tcphdr *th;
559
560 if (!pskb_may_pull(skb, sizeof(*th)))
561 return -EINVAL;
562
563 ipv6h = skb->nh.ipv6h;
564 th = skb->h.th;
565
566 th->check = 0;
567 th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,
568 IPPROTO_TCP, 0);
569 skb->csum = offsetof(struct tcphdr, check);
570 skb->ip_summed = CHECKSUM_HW;
571 return 0;
572}
555 573
556static void tcp_v6_send_reset(struct sk_buff *skb) 574static void tcp_v6_send_reset(struct sk_buff *skb)
557{ 575{
@@ -1603,6 +1621,7 @@ struct proto tcpv6_prot = {
1603static struct inet6_protocol tcpv6_protocol = { 1621static struct inet6_protocol tcpv6_protocol = {
1604 .handler = tcp_v6_rcv, 1622 .handler = tcp_v6_rcv,
1605 .err_handler = tcp_v6_err, 1623 .err_handler = tcp_v6_err,
1624 .gso_send_check = tcp_v6_gso_send_check,
1606 .gso_segment = tcp_tso_segment, 1625 .gso_segment = tcp_tso_segment,
1607 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, 1626 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1608}; 1627};