Skip to content

Commit 21f4d45

Browse files
0x7f454c46kuba-moo
authored andcommitted
net/ip6_tunnel: Prevent perpetual tunnel growth
Similarly to ipv4 tunnel, ipv6 version updates dev->needed_headroom, too. While ipv4 tunnel headroom adjustment growth was limited in commit 5ae1e99 ("net: ip_tunnel: prevent perpetual headroom growth"), ipv6 tunnel yet increases the headroom without any ceiling. Reflect ipv4 tunnel headroom adjustment limit on ipv6 version. Credits to Francesco Ruggeri, who was originally debugging this issue and wrote local Arista-specific patch and a reproducer. Fixes: 8eb30be ("ipv6: Create ip6_tnl_xmit") Cc: Florian Westphal <fw@strlen.de> Cc: Francesco Ruggeri <fruggeri05@gmail.com> Signed-off-by: Dmitry Safonov <dima@arista.com> Link: https://patch.msgid.link/20251009-ip6_tunnel-headroom-v2-1-8e4dbd8f7e35@arista.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent e4d0c90 commit 21f4d45

File tree

3 files changed

+16
-16
lines changed

3 files changed

+16
-16
lines changed

include/net/ip_tunnels.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,21 @@ struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md,
611611
int skb_tunnel_check_pmtu(struct sk_buff *skb, struct dst_entry *encap_dst,
612612
int headroom, bool reply);
613613

614+
static inline void ip_tunnel_adj_headroom(struct net_device *dev,
615+
unsigned int headroom)
616+
{
617+
/* we must cap headroom to some upperlimit, else pskb_expand_head
618+
* will overflow header offsets in skb_headers_offset_update().
619+
*/
620+
const unsigned int max_allowed = 512;
621+
622+
if (headroom > max_allowed)
623+
headroom = max_allowed;
624+
625+
if (headroom > READ_ONCE(dev->needed_headroom))
626+
WRITE_ONCE(dev->needed_headroom, headroom);
627+
}
628+
614629
int iptunnel_handle_offloads(struct sk_buff *skb, int gso_type_mask);
615630

616631
static inline int iptunnel_pull_offloads(struct sk_buff *skb)

net/ipv4/ip_tunnel.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -568,20 +568,6 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
568568
return 0;
569569
}
570570

571-
static void ip_tunnel_adj_headroom(struct net_device *dev, unsigned int headroom)
572-
{
573-
/* we must cap headroom to some upperlimit, else pskb_expand_head
574-
* will overflow header offsets in skb_headers_offset_update().
575-
*/
576-
static const unsigned int max_allowed = 512;
577-
578-
if (headroom > max_allowed)
579-
headroom = max_allowed;
580-
581-
if (headroom > READ_ONCE(dev->needed_headroom))
582-
WRITE_ONCE(dev->needed_headroom, headroom);
583-
}
584-
585571
void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
586572
u8 proto, int tunnel_hlen)
587573
{

net/ipv6/ip6_tunnel.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,8 +1257,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
12571257
*/
12581258
max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(struct ipv6hdr)
12591259
+ dst->header_len + t->hlen;
1260-
if (max_headroom > READ_ONCE(dev->needed_headroom))
1261-
WRITE_ONCE(dev->needed_headroom, max_headroom);
1260+
ip_tunnel_adj_headroom(dev, max_headroom);
12621261

12631262
err = ip6_tnl_encap(skb, t, &proto, fl6);
12641263
if (err)

0 commit comments

Comments
 (0)