diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c index 61c6a27bf202..ecd8146089ee 100644 --- a/net/ipv6/seg6_iptunnel.c +++ b/net/ipv6/seg6_iptunnel.c @@ -400,6 +400,7 @@ static int seg6_do_srh(struct sk_buff *skb, struct dst_entry *cache_dst) struct dst_entry *dst = skb_dst(skb); struct seg6_iptunnel_encap *tinfo; struct seg6_lwt *slwt; + unsigned int headroom; int proto, err = 0; slwt = seg6_lwt_lwtunnel(dst->lwtstate); @@ -446,8 +447,13 @@ static int seg6_do_srh(struct sk_buff *skb, struct dst_entry *cache_dst) if (!skb_mac_header_was_set(skb)) return -EINVAL; - if (pskb_expand_head(skb, skb->mac_len, 0, GFP_ATOMIC) < 0) - return -ENOMEM; + headroom = skb->mac_len + sizeof(struct ipv6hdr) + + ipv6_optlen(tinfo->srh) + + dst_dev_overhead(cache_dst, skb); + + err = skb_cow_head(skb, headroom); + if (unlikely(err)) + return err; skb_mac_header_rebuild(skb); skb_push(skb, skb->mac_len);