summaryrefslogtreecommitdiffstats
path: root/net/ipv6/af_inet6.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-05-26 20:50:28 +0200
committerDavid S. Miller <davem@davemloft.net>2009-05-27 12:26:01 +0200
commita5b1cf288d4200506ab62fbb86cc81ace948a306 (patch)
treec95339866f4d67220d111811a92e5c6b79de6ab4 /net/ipv6/af_inet6.c
parentgro: Optimise length comparison in skb_gro_header (diff)
downloadlinux-a5b1cf288d4200506ab62fbb86cc81ace948a306.tar.xz
linux-a5b1cf288d4200506ab62fbb86cc81ace948a306.zip
gro: Avoid unnecessary comparison after skb_gro_header
For the overwhelming majority of cases, skb_gro_header's return value cannot be NULL. Yet we must check it because of its current form. This patch splits it up into multiple functions in order to avoid this. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/af_inet6.c')
-rw-r--r--net/ipv6/af_inet6.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 61f55386a236..b6215be0963f 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -817,13 +817,20 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
struct sk_buff *p;
struct ipv6hdr *iph;
unsigned int nlen;
+ unsigned int hlen;
+ unsigned int off;
int flush = 1;
int proto;
__wsum csum;
- iph = skb_gro_header(skb, sizeof(*iph));
- if (unlikely(!iph))
- goto out;
+ off = skb_gro_offset(skb);
+ hlen = off + sizeof(*iph);
+ iph = skb_gro_header_fast(skb, off);
+ if (skb_gro_header_hard(skb, hlen)) {
+ iph = skb_gro_header_slow(skb, hlen, off);
+ if (unlikely(!iph))
+ goto out;
+ }
skb_gro_pull(skb, sizeof(*iph));
skb_set_transport_header(skb, skb_gro_offset(skb));