This is a note to let you know that I've just added the patch titled vxlan: Pull inner IP header in vxlan_xmit_one(). to the 6.9-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: vxlan-pull-inner-ip-header-in-vxlan_xmit_one.patch and it can be found in the queue-6.9 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit c2469c4cb7c9120e08d567e078d09355fe0fdab0 Author: Guillaume Nault <gnault@xxxxxxxxxx> Date: Wed Jun 19 15:34:57 2024 +0200 vxlan: Pull inner IP header in vxlan_xmit_one(). [ Upstream commit 31392048f55f98cb01ca709d32d06d926ab9760a ] Ensure the inner IP header is part of the skb's linear data before setting old_iph. Otherwise, on a non-linear skb, old_iph could point outside of the packet data. Unlike classical VXLAN, which always encapsulates Ethernet packets, VXLAN-GPE can transport IP packets directly. In that case, we need to look at skb->protocol to figure out if an Ethernet header is present. Fixes: d342894c5d2f ("vxlan: virtual extensible lan") Signed-off-by: Guillaume Nault <gnault@xxxxxxxxxx> Link: https://patch.msgid.link/2aa75f6fa62ac9dbe4f16ad5ba75dd04a51d4b99.1718804000.git.gnault@xxxxxxxxxx Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index b2d054f59f30f..49779ba3c4b7b 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -2336,7 +2336,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, struct ip_tunnel_key *pkey; struct ip_tunnel_key key; struct vxlan_dev *vxlan = netdev_priv(dev); - const struct iphdr *old_iph = ip_hdr(skb); + const struct iphdr *old_iph; struct vxlan_metadata _md; struct vxlan_metadata *md = &_md; unsigned int pkt_len = skb->len; @@ -2350,8 +2350,15 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, bool use_cache; bool udp_sum = false; bool xnet = !net_eq(vxlan->net, dev_net(vxlan->dev)); + bool no_eth_encap; __be32 vni = 0; + no_eth_encap = flags & VXLAN_F_GPE && skb->protocol != htons(ETH_P_TEB); + if (!skb_vlan_inet_prepare(skb, no_eth_encap)) + goto drop; + + old_iph = ip_hdr(skb); + info = skb_tunnel_info(skb); use_cache = ip_tunnel_dst_cache_usable(skb, info);