Skip to content

Commit 1308591

Browse files
0x7f454c46Ulrich Hecht
authored andcommitted
net/ip6_tunnel: Prevent perpetual tunnel growth
[ Upstream commit 21f4d45eba0b2dcae5dbc9e5e0ad08735c993f16 ] Similarly to ipv4 tunnel, ipv6 version updates dev->needed_headroom, too. While ipv4 tunnel headroom adjustment growth was limited in commit 5ae1e9922bbd ("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> Signed-off-by: Sasha Levin <sashal@kernel.org> [uli: backport to 4.19] Signed-off-by: Ulrich Hecht <uli@kernel.org>
1 parent fe02654 commit 1308591

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

include/net/ip_tunnels.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,21 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
467467
struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md,
468468
gfp_t flags);
469469

470+
static inline void ip_tunnel_adj_headroom(struct net_device *dev,
471+
unsigned int headroom)
472+
{
473+
/* we must cap headroom to some upperlimit, else pskb_expand_head
474+
* will overflow header offsets in skb_headers_offset_update().
475+
*/
476+
const unsigned int max_allowed = 512;
477+
478+
if (headroom > max_allowed)
479+
headroom = max_allowed;
480+
481+
if (headroom > READ_ONCE(dev->needed_headroom))
482+
WRITE_ONCE(dev->needed_headroom, headroom);
483+
}
484+
470485
int iptunnel_handle_offloads(struct sk_buff *skb, int gso_type_mask);
471486

472487
static inline int iptunnel_pull_offloads(struct sk_buff *skb)

net/ipv6/ip6_tunnel.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,8 +1206,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
12061206
*/
12071207
max_headroom = LL_RESERVED_SPACE(dst->dev) + sizeof(struct ipv6hdr)
12081208
+ dst->header_len + t->hlen;
1209-
if (max_headroom > READ_ONCE(dev->needed_headroom))
1210-
WRITE_ONCE(dev->needed_headroom, max_headroom);
1209+
ip_tunnel_adj_headroom(dev, max_headroom);
12111210

12121211
err = ip6_tnl_encap(skb, t, &proto, fl6);
12131212
if (err)

0 commit comments

Comments
 (0)