diff options
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r-- | net/ipv4/af_inet.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 8d157157bf8e..318d4674faa1 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1106,7 +1106,15 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) int ihl; int id; - if (!pskb_may_pull(skb, sizeof(*iph))) + if (unlikely(skb_shinfo(skb)->gso_type & + ~(SKB_GSO_TCPV4 | + SKB_GSO_UDP | + SKB_GSO_DODGY | + SKB_GSO_TCP_ECN | + 0))) + goto out; + + if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) goto out; iph = skb->nh.iph; @@ -1114,7 +1122,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) if (ihl < sizeof(*iph)) goto out; - if (!pskb_may_pull(skb, ihl)) + if (unlikely(!pskb_may_pull(skb, ihl))) goto out; skb->h.raw = __skb_pull(skb, ihl); @@ -1125,7 +1133,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) rcu_read_lock(); ops = rcu_dereference(inet_protos[proto]); - if (ops && ops->gso_segment) + if (likely(ops && ops->gso_segment)) segs = ops->gso_segment(skb, features); rcu_read_unlock(); |