|
|
@@ -62,26 +62,26 @@ EXPORT_SYMBOL_GPL(gre_del_protocol);
|
|
|
|
|
|
/* Fills in tpi and returns header length to be pulled. */
|
|
|
int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
|
|
|
- bool *csum_err, __be16 proto)
|
|
|
+ bool *csum_err, __be16 proto, int nhs)
|
|
|
{
|
|
|
const struct gre_base_hdr *greh;
|
|
|
__be32 *options;
|
|
|
int hdr_len;
|
|
|
|
|
|
- if (unlikely(!pskb_may_pull(skb, sizeof(struct gre_base_hdr))))
|
|
|
+ if (unlikely(!pskb_may_pull(skb, nhs + sizeof(struct gre_base_hdr))))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- greh = (struct gre_base_hdr *)skb_transport_header(skb);
|
|
|
+ greh = (struct gre_base_hdr *)(skb->data + nhs);
|
|
|
if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING)))
|
|
|
return -EINVAL;
|
|
|
|
|
|
tpi->flags = gre_flags_to_tnl_flags(greh->flags);
|
|
|
hdr_len = gre_calc_hlen(tpi->flags);
|
|
|
|
|
|
- if (!pskb_may_pull(skb, hdr_len))
|
|
|
+ if (!pskb_may_pull(skb, nhs + hdr_len))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- greh = (struct gre_base_hdr *)skb_transport_header(skb);
|
|
|
+ greh = (struct gre_base_hdr *)(skb->data + nhs);
|
|
|
tpi->proto = greh->protocol;
|
|
|
|
|
|
options = (__be32 *)(greh + 1);
|