diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2009-04-27 08:44:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-27 08:44:29 -0400 |
commit | edbd9e30306067c3a45c035eb95a6f49daaa2337 (patch) | |
tree | 00e8ce4bbb0b517cea71ff14165b2b1d944d22f3 /net | |
parent | 56ed4351c2604c221a82276f51e5dfd467921bf3 (diff) |
gro: Fix handling of headers that extend over the tail
The skb_gro_* code fails to handle the case where a header starts
in the linear area but ends in the frags area. Since the goal
of skb_gro_* is to optimise the case of completely non-linear
packets, we can simply bail out if we have anything in the linear
area.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 11 |
1 files changed, 3 insertions, 8 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index e48c08af76ad..6785b067ad50 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2378,18 +2378,13 @@ void *skb_gro_header(struct sk_buff *skb, unsigned int hlen) | |||
2378 | unsigned int offset = skb_gro_offset(skb); | 2378 | unsigned int offset = skb_gro_offset(skb); |
2379 | 2379 | ||
2380 | hlen += offset; | 2380 | hlen += offset; |
2381 | if (hlen <= skb_headlen(skb)) | 2381 | if (unlikely(skb_headlen(skb) || |
2382 | return skb->data + offset; | 2382 | skb_shinfo(skb)->frags[0].size < hlen || |
2383 | |||
2384 | if (unlikely(!skb_shinfo(skb)->nr_frags || | ||
2385 | skb_shinfo(skb)->frags[0].size <= | ||
2386 | hlen - skb_headlen(skb) || | ||
2387 | PageHighMem(skb_shinfo(skb)->frags[0].page))) | 2383 | PageHighMem(skb_shinfo(skb)->frags[0].page))) |
2388 | return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; | 2384 | return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; |
2389 | 2385 | ||
2390 | return page_address(skb_shinfo(skb)->frags[0].page) + | 2386 | return page_address(skb_shinfo(skb)->frags[0].page) + |
2391 | skb_shinfo(skb)->frags[0].page_offset + | 2387 | skb_shinfo(skb)->frags[0].page_offset + offset; |
2392 | offset - skb_headlen(skb); | ||
2393 | } | 2388 | } |
2394 | EXPORT_SYMBOL(skb_gro_header); | 2389 | EXPORT_SYMBOL(skb_gro_header); |
2395 | 2390 | ||