diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2006-07-08 16:34:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-07-08 16:34:56 -0400 |
commit | a430a43d087545c96542ee64573237919109d370 (patch) | |
tree | 653b630298505d5a65e2e094868d83014e4b0dc4 /include | |
parent | 89114afd435a486deb8583e89f490fc274444d18 (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 'include')
-rw-r--r-- | include/linux/netdevice.h | 8 | ||||
-rw-r--r-- | include/net/protocol.h | 2 | ||||
-rw-r--r-- | include/net/tcp.h | 1 |
3 files changed, 8 insertions, 3 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 0359a6430018..76cc099c8580 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -549,6 +549,7 @@ struct packet_type { | |||
549 | struct net_device *); | 549 | struct net_device *); |
550 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, | 550 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, |
551 | int features); | 551 | int features); |
552 | int (*gso_send_check)(struct sk_buff *skb); | ||
552 | void *af_packet_priv; | 553 | void *af_packet_priv; |
553 | struct list_head list; | 554 | struct list_head list; |
554 | }; | 555 | }; |
@@ -1001,13 +1002,14 @@ static inline int net_gso_ok(int features, int gso_type) | |||
1001 | 1002 | ||
1002 | static inline int skb_gso_ok(struct sk_buff *skb, int features) | 1003 | static inline int skb_gso_ok(struct sk_buff *skb, int features) |
1003 | { | 1004 | { |
1004 | return net_gso_ok(features, skb_is_gso(skb) ? | 1005 | return net_gso_ok(features, skb_shinfo(skb)->gso_type); |
1005 | skb_shinfo(skb)->gso_type : 0); | ||
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) | 1008 | static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) |
1009 | { | 1009 | { |
1010 | return !skb_gso_ok(skb, dev->features); | 1010 | return skb_is_gso(skb) && |
1011 | (!skb_gso_ok(skb, dev->features) || | ||
1012 | unlikely(skb->ip_summed != CHECKSUM_HW)); | ||
1011 | } | 1013 | } |
1012 | 1014 | ||
1013 | #endif /* __KERNEL__ */ | 1015 | #endif /* __KERNEL__ */ |
diff --git a/include/net/protocol.h b/include/net/protocol.h index a225d6371cb1..c643bce64e55 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h | |||
@@ -36,6 +36,7 @@ | |||
36 | struct net_protocol { | 36 | struct net_protocol { |
37 | int (*handler)(struct sk_buff *skb); | 37 | int (*handler)(struct sk_buff *skb); |
38 | void (*err_handler)(struct sk_buff *skb, u32 info); | 38 | void (*err_handler)(struct sk_buff *skb, u32 info); |
39 | int (*gso_send_check)(struct sk_buff *skb); | ||
39 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, | 40 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, |
40 | int features); | 41 | int features); |
41 | int no_policy; | 42 | int no_policy; |
@@ -51,6 +52,7 @@ struct inet6_protocol | |||
51 | int type, int code, int offset, | 52 | int type, int code, int offset, |
52 | __u32 info); | 53 | __u32 info); |
53 | 54 | ||
55 | int (*gso_send_check)(struct sk_buff *skb); | ||
54 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, | 56 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, |
55 | int features); | 57 | int features); |
56 | 58 | ||
diff --git a/include/net/tcp.h b/include/net/tcp.h index 3cd803b0d7a5..0720bddff1e9 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -1086,6 +1086,7 @@ extern struct request_sock_ops tcp_request_sock_ops; | |||
1086 | 1086 | ||
1087 | extern int tcp_v4_destroy_sock(struct sock *sk); | 1087 | extern int tcp_v4_destroy_sock(struct sock *sk); |
1088 | 1088 | ||
1089 | extern int tcp_v4_gso_send_check(struct sk_buff *skb); | ||
1089 | extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features); | 1090 | extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features); |
1090 | 1091 | ||
1091 | #ifdef CONFIG_PROC_FS | 1092 | #ifdef CONFIG_PROC_FS |