diff options
author | Pravin B Shelar <pshelar@nicira.com> | 2013-02-11 04:27:41 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-02-13 13:30:10 -0500 |
commit | c9af6db4c11ccc6c3e7f19bbc15d54023956f97c (patch) | |
tree | c596e747d8940b848931ac31701e245a6c0efaf6 /include | |
parent | b8fa4100350432504df438014e2e5e9c1bbb6325 (diff) |
net: Fix possible wrong checksum generation.
Patch cef401de7be8c4e (net: fix possible wrong checksum
generation) fixed wrong checksum calculation but it broke TSO by
defining new GSO type but not a netdev feature for that type.
net_gso_ok() would not allow hardware checksum/segmentation
offload of such packets without the feature.
Following patch fixes TSO and wrong checksum. This patch uses
same logic that Eric Dumazet used. Patch introduces new flag
SKBTX_SHARED_FRAG if at least one frag can be modified by
the user. but SKBTX_SHARED_FRAG flag is kept in skb shared
info tx_flags rather than gso_type.
tx_flags is better compared to gso_type since we can have skb with
shared frag without gso packet. It does not link SHARED_FRAG to
GSO, So there is no need to define netdev feature for this.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/skbuff.h | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index d7573c37a51d..9da99520ccd5 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -230,6 +230,13 @@ enum { | |||
230 | 230 | ||
231 | /* generate wifi status information (where possible) */ | 231 | /* generate wifi status information (where possible) */ |
232 | SKBTX_WIFI_STATUS = 1 << 4, | 232 | SKBTX_WIFI_STATUS = 1 << 4, |
233 | |||
234 | /* This indicates at least one fragment might be overwritten | ||
235 | * (as in vmsplice(), sendfile() ...) | ||
236 | * If we need to compute a TX checksum, we'll need to copy | ||
237 | * all frags to avoid possible bad checksum | ||
238 | */ | ||
239 | SKBTX_SHARED_FRAG = 1 << 5, | ||
233 | }; | 240 | }; |
234 | 241 | ||
235 | /* | 242 | /* |
@@ -307,13 +314,6 @@ enum { | |||
307 | SKB_GSO_TCPV6 = 1 << 4, | 314 | SKB_GSO_TCPV6 = 1 << 4, |
308 | 315 | ||
309 | SKB_GSO_FCOE = 1 << 5, | 316 | SKB_GSO_FCOE = 1 << 5, |
310 | |||
311 | /* This indicates at least one fragment might be overwritten | ||
312 | * (as in vmsplice(), sendfile() ...) | ||
313 | * If we need to compute a TX checksum, we'll need to copy | ||
314 | * all frags to avoid possible bad checksum | ||
315 | */ | ||
316 | SKB_GSO_SHARED_FRAG = 1 << 6, | ||
317 | }; | 317 | }; |
318 | 318 | ||
319 | #if BITS_PER_LONG > 32 | 319 | #if BITS_PER_LONG > 32 |
@@ -2220,7 +2220,8 @@ static inline int skb_linearize(struct sk_buff *skb) | |||
2220 | */ | 2220 | */ |
2221 | static inline bool skb_has_shared_frag(const struct sk_buff *skb) | 2221 | static inline bool skb_has_shared_frag(const struct sk_buff *skb) |
2222 | { | 2222 | { |
2223 | return skb_shinfo(skb)->gso_type & SKB_GSO_SHARED_FRAG; | 2223 | return skb_is_nonlinear(skb) && |
2224 | skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG; | ||
2224 | } | 2225 | } |
2225 | 2226 | ||
2226 | /** | 2227 | /** |