int (*okfn)(struct sk_buff *))
{
struct iphdr *iph;
- __u32 len;
struct sk_buff *skb = *pskb;
+ __u32 len = nf_bridge_encap_header_len(skb);
+
+ if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+ return NF_STOLEN;
+
+ if (unlikely(!pskb_may_pull(skb, len)))
+ goto out;
if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) ||
IS_PPPOE_IPV6(skb)) {
if (!brnf_call_ip6tables)
return NF_ACCEPT;
#endif
- if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL)
- goto out;
nf_bridge_pull_encap_header_rcsum(skb);
return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
}
!IS_PPPOE_IP(skb))
return NF_ACCEPT;
- if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL)
- goto out;
nf_bridge_pull_encap_header_rcsum(skb);
if (!pskb_may_pull(skb, sizeof(struct iphdr)))