]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
vxlan: use pskb_network_may_pull() for transmit path header pulls
authorEric Dumazet <edumazet@google.com>
Thu, 23 Jul 2026 14:42:49 +0000 (14:42 +0000)
committerJakub Kicinski <kuba@kernel.org>
Mon, 27 Jul 2026 22:16:15 +0000 (15:16 -0700)
In vxlan_xmit(), arp_reduce(), and vxlan_mdb_entry_skb_get(), pskb_may_pull() was
being called to verify the availability of network layer headers (ARP, IPv6/ND,
IP/IPv6 MDB keys).

However, during transmit skb->data points to the MAC header, so skb_network_offset(skb)
is ETH_HLEN (14 bytes). Using pskb_may_pull(skb, len) only checks len bytes from skb->data
rather than skb_network_offset(skb) + len, which can leave part of the network header
in non-linear frags.

Replace these remaining pskb_may_pull() calls with pskb_network_may_pull() to properly
account for the MAC header offset.

Fixes: e4f67addf158 ("add DOVE extensions for VXLAN")
Fixes: f564f45c4518 ("vxlan: add ipv6 proxy support")
Fixes: 0f83e69f44bf ("vxlan: Add MDB data path support")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: stable@vger.kernel.org
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260723144249.759100-6-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/vxlan/vxlan_core.c
drivers/net/vxlan/vxlan_mdb.c

index 2163e2687db029e19fefdf279095209e94b18a41..1ded27768a97c2fa8dfe61eaa54dc9b8f7a2ce76 100644 (file)
@@ -1850,7 +1850,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
        if (dev->flags & IFF_NOARP)
                goto out;
 
-       if (!pskb_may_pull(skb, arp_hdr_len(dev))) {
+       if (!pskb_network_may_pull(skb, arp_hdr_len(dev))) {
                dev_dstats_tx_dropped(dev);
                vxlan_vnifilter_count(vxlan, vni, NULL,
                                      VXLAN_VNI_STATS_TX_DROPS, 0);
@@ -2763,8 +2763,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
                        return arp_reduce(dev, skb, vni);
 #if IS_ENABLED(CONFIG_IPV6)
                else if (ntohs(eth->h_proto) == ETH_P_IPV6 &&
-                        pskb_may_pull(skb, sizeof(struct ipv6hdr) +
-                                           sizeof(struct nd_msg)) &&
+                        pskb_network_may_pull(skb, sizeof(struct ipv6hdr) +
+                                                   sizeof(struct nd_msg)) &&
                         ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
                        struct nd_msg *m = (struct nd_msg *)(ipv6_hdr(skb) + 1);
 
index af7a0d7f95a57a17486a8ecc277b7bb9d921a061..9a9038ae90c18c5f0e4362b2b254b0c48dfdad0e 100644 (file)
@@ -1631,7 +1631,7 @@ struct vxlan_mdb_entry *vxlan_mdb_entry_skb_get(struct vxlan_dev *vxlan,
 
        switch (skb->protocol) {
        case htons(ETH_P_IP):
-               if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+               if (!pskb_network_may_pull(skb, sizeof(struct iphdr)))
                        return NULL;
                group.dst.sa.sa_family = AF_INET;
                group.dst.sin.sin_addr.s_addr = ip_hdr(skb)->daddr;
@@ -1640,7 +1640,7 @@ struct vxlan_mdb_entry *vxlan_mdb_entry_skb_get(struct vxlan_dev *vxlan,
                break;
 #if IS_ENABLED(CONFIG_IPV6)
        case htons(ETH_P_IPV6):
-               if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+               if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
                        return NULL;
                group.dst.sa.sa_family = AF_INET6;
                group.dst.sin6.sin6_addr = ipv6_hdr(skb)->daddr;