]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: gre: fix lltx regression for GRE tunnels with SEQ/CSUM
authorYun Zhou <yun.zhou@windriver.com>
Mon, 13 Jul 2026 15:09:45 +0000 (23:09 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 23 Jul 2026 11:01:57 +0000 (13:01 +0200)
Before commit 00d066a4d4ed ("netdev_features: convert NETIF_F_LLTX to
dev->lltx"), NETIF_F_LLTX was set unconditionally in both
__gre_tunnel_init() and ip6gre_tnl_init_features() alongside
GRE_FEATURES:

    dev->features |= GRE_FEATURES | NETIF_F_LLTX;

When that commit converted NETIF_F_LLTX to the dev->lltx flag, it
placed 'dev->lltx = true' after the SEQ/CSUM early returns instead
of before them. This causes GRE/GRETAP/ip6gre tunnels with SEQ or
CSUM+encap to lose lockless TX, reintroducing _xmit_lock acquisition
around their ndo_start_xmit. Since GRE xmit re-enters the stack via
ip_tunnel_xmit(), holding _xmit_lock risks ABBA deadlock with the
underlay device.

  CPU0                        CPU1
  ----                        ----
  lock(&qdisc_xmit_lock_key#6);
                              lock(&qdisc_xmit_lock_key#3);
                              lock(&qdisc_xmit_lock_key#6);
  lock(&qdisc_xmit_lock_key#3);

Fix by moving dev->lltx = true before the early returns in both
functions, restoring the original unconditional behavior.

Fixes: 00d066a4d4ed ("netdev_features: convert NETIF_F_LLTX to dev->lltx")
Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260713150945.1779628-1-yun.zhou@windriver.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/ipv4/ip_gre.c
net/ipv6/ip6_gre.c

index 3efdfb4ffa2112db3b056169d02d28e8853873ae..0ba1e94e9012c626d31d076e94c3a38d0e32e996 100644 (file)
@@ -1018,6 +1018,8 @@ static void __gre_tunnel_init(struct net_device *dev)
        dev->features           |= GRE_FEATURES;
        dev->hw_features        |= GRE_FEATURES;
 
+       dev->lltx = true;
+
        /* TCP offload with GRE SEQ is not supported, nor can we support 2
         * levels of outer headers requiring an update.
         */
@@ -1029,8 +1031,6 @@ static void __gre_tunnel_init(struct net_device *dev)
 
        dev->features |= NETIF_F_GSO_SOFTWARE;
        dev->hw_features |= NETIF_F_GSO_SOFTWARE;
-
-       dev->lltx = true;
 }
 
 static int ipgre_tunnel_init(struct net_device *dev)
index 7c09a269b3521618e264655ad2b93586f7214b0b..b843116e9b703c701a1a28a85569501d83ede21d 100644 (file)
@@ -1455,6 +1455,8 @@ static void ip6gre_tnl_init_features(struct net_device *dev)
        dev->features           |= GRE6_FEATURES;
        dev->hw_features        |= GRE6_FEATURES;
 
+       dev->lltx = true;
+
        /* TCP offload with GRE SEQ is not supported, nor can we support 2
         * levels of outer headers requiring an update.
         */
@@ -1466,8 +1468,6 @@ static void ip6gre_tnl_init_features(struct net_device *dev)
 
        dev->features |= NETIF_F_GSO_SOFTWARE;
        dev->hw_features |= NETIF_F_GSO_SOFTWARE;
-
-       dev->lltx = true;
 }
 
 static int ip6gre_tunnel_init_common(struct net_device *dev)