]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop some udp 6.15 patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Jun 2025 13:13:02 +0000 (15:13 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Jun 2025 13:13:02 +0000 (15:13 +0200)
queue-6.15/series
queue-6.15/udp-properly-deal-with-xfrm-encap-and-addrform.patch [deleted file]
queue-6.15/udp_tunnel-create-a-fastpath-gro-lookup.patch [deleted file]
queue-6.15/udp_tunnel-use-static-call-for-gro-hooks-when-possib.patch [deleted file]

index b1cb45e4a0ee7da8e1bd1c910e6fe5ed3729999e..631d8c822f9a094265c1e3301d0b1800b60c320a 100644 (file)
@@ -182,9 +182,6 @@ wifi-ath12k-fix-ath12k_flag_registered-flag-handling.patch
 f2fs-clean-up-unnecessary-indentation.patch
 f2fs-prevent-the-current-section-from-being-selected.patch
 f2fs-fix-to-do-sanity-check-on-sbi-total_valid_block.patch
-udp_tunnel-create-a-fastpath-gro-lookup.patch
-udp_tunnel-use-static-call-for-gro-hooks-when-possib.patch
-udp-properly-deal-with-xfrm-encap-and-addrform.patch
 page_pool-move-pp_magic-check-into-helper-functions.patch
 page_pool-track-dma-mapped-pages-and-unmap-them-when.patch
 net-mlx5-hws-fix-matcher-action-template-attach.patch
diff --git a/queue-6.15/udp-properly-deal-with-xfrm-encap-and-addrform.patch b/queue-6.15/udp-properly-deal-with-xfrm-encap-and-addrform.patch
deleted file mode 100644 (file)
index 3978af2..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-From 7379d064b4e3a412604ed33592bdaee2468b6c95 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 9 Apr 2025 22:00:56 +0200
-Subject: udp: properly deal with xfrm encap and ADDRFORM
-
-From: Paolo Abeni <pabeni@redhat.com>
-
-[ Upstream commit c26c192c3d486a2a7d83d254bae294c2f8f50abf ]
-
-UDP GRO accounting assumes that the GRO receive callback is always
-set when the UDP tunnel is enabled, but syzkaller proved otherwise,
-leading tot the following splat:
-
-WARNING: CPU: 0 PID: 5837 at net/ipv4/udp_offload.c:123 udp_tunnel_update_gro_rcv+0x28d/0x4c0 net/ipv4/udp_offload.c:123
-Modules linked in:
-CPU: 0 UID: 0 PID: 5837 Comm: syz-executor850 Not tainted 6.14.0-syzkaller-13320-g420aabef3ab5 #0 PREEMPT(full)
-Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025
-RIP: 0010:udp_tunnel_update_gro_rcv+0x28d/0x4c0 net/ipv4/udp_offload.c:123
-Code: 00 00 e8 c6 5a 2f f7 48 c1 e5 04 48 8d b5 20 53 c7 9a ba 10
-      00 00 00 4c 89 ff e8 ce 87 99 f7 e9 ce 00 00 00 e8 a4 5a 2f
-      f7 90 <0f> 0b 90 e9 de fd ff ff bf 01 00 00 00 89 ee e8 cf
-      5e 2f f7 85 ed
-RSP: 0018:ffffc90003effa88 EFLAGS: 00010293
-RAX: ffffffff8a93fc9c RBX: 0000000000000000 RCX: ffff8880306f9e00
-RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
-RBP: 0000000000000000 R08: ffffffff8a93fabe R09: 1ffffffff20bfb2e
-R10: dffffc0000000000 R11: fffffbfff20bfb2f R12: ffff88814ef21738
-R13: dffffc0000000000 R14: ffff88814ef21778 R15: 1ffff11029de42ef
-FS:  0000000000000000(0000) GS:ffff888124f96000(0000) knlGS:0000000000000000
-CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
-CR2: 00007f04eec760d0 CR3: 000000000eb38000 CR4: 00000000003526f0
-DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
-DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
-Call Trace:
- <TASK>
- udp_tunnel_cleanup_gro include/net/udp_tunnel.h:205 [inline]
- udpv6_destroy_sock+0x212/0x270 net/ipv6/udp.c:1829
- sk_common_release+0x71/0x2e0 net/core/sock.c:3896
- inet_release+0x17d/0x200 net/ipv4/af_inet.c:435
- __sock_release net/socket.c:647 [inline]
- sock_close+0xbc/0x240 net/socket.c:1391
- __fput+0x3e9/0x9f0 fs/file_table.c:465
- task_work_run+0x251/0x310 kernel/task_work.c:227
- exit_task_work include/linux/task_work.h:40 [inline]
- do_exit+0xa11/0x27f0 kernel/exit.c:953
- do_group_exit+0x207/0x2c0 kernel/exit.c:1102
- __do_sys_exit_group kernel/exit.c:1113 [inline]
- __se_sys_exit_group kernel/exit.c:1111 [inline]
- __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1111
- x64_sys_call+0x26c3/0x26d0 arch/x86/include/generated/asm/syscalls_64.h:232
- do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
- do_syscall_64+0xf3/0x230 arch/x86/entry/syscall_64.c:94
- entry_SYSCALL_64_after_hwframe+0x77/0x7f
-RIP: 0033:0x7f04eebfac79
-Code: Unable to access opcode bytes at 0x7f04eebfac4f.
-RSP: 002b:00007fffdcaa34a8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
-RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f04eebfac79
-RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000000
-RBP: 00007f04eec75270 R08: ffffffffffffffb8 R09: 00007fffdcaa36c8
-R10: 0000200000000000 R11: 0000000000000246 R12: 00007f04eec75270
-R13: 0000000000000000 R14: 00007f04eec75cc0 R15: 00007f04eebcca70
-
-Address the issue moving the accounting hook into
-setup_udp_tunnel_sock() and set_xfrm_gro_udp_encap_rcv(), where
-the GRO callback is actually set.
-
-set_xfrm_gro_udp_encap_rcv() is prone to races with IPV6_ADDRFORM,
-run the relevant setsockopt under the socket lock to ensure using
-consistent values of sk_family and up->encap_type.
-
-Refactor the GRO callback selection code, to make it clear that
-the function pointer is always initialized.
-
-Reported-by: syzbot+8c469a2260132cd095c1@syzkaller.appspotmail.com
-Closes: https://syzkaller.appspot.com/bug?extid=8c469a2260132cd095c1
-Fixes: 172bf009c18d ("xfrm: Support GRO for IPv4 ESP in UDP encapsulation")
-Fixes: 5d7f5b2f6b935 ("udp_tunnel: use static call for GRO hooks when possible")
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
-Link: https://patch.msgid.link/92bcdb6899145a9a387c8fa9e3ca656642a43634.1744228733.git.pabeni@redhat.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/net/udp_tunnel.h   |  1 -
- net/ipv4/udp.c             | 31 ++++++++++++++++++++++++++-----
- net/ipv4/udp_tunnel_core.c |  2 ++
- 3 files changed, 28 insertions(+), 6 deletions(-)
-
-diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
-index 288f06f23a804..2df3b8344eb52 100644
---- a/include/net/udp_tunnel.h
-+++ b/include/net/udp_tunnel.h
-@@ -215,7 +215,6 @@ static inline void udp_tunnel_encap_enable(struct sock *sk)
-       if (READ_ONCE(sk->sk_family) == PF_INET6)
-               ipv6_stub->udpv6_encap_enable();
- #endif
--      udp_tunnel_update_gro_rcv(sk, true);
-       udp_encap_enable();
- }
-diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
-index 04cd3353f1d46..af943b905804a 100644
---- a/net/ipv4/udp.c
-+++ b/net/ipv4/udp.c
-@@ -2904,15 +2904,33 @@ void udp_destroy_sock(struct sock *sk)
-       }
- }
-+typedef struct sk_buff *(*udp_gro_receive_t)(struct sock *sk,
-+                                           struct list_head *head,
-+                                           struct sk_buff *skb);
-+
- static void set_xfrm_gro_udp_encap_rcv(__u16 encap_type, unsigned short family,
-                                      struct sock *sk)
- {
- #ifdef CONFIG_XFRM
-+      udp_gro_receive_t new_gro_receive;
-+
-       if (udp_test_bit(GRO_ENABLED, sk) && encap_type == UDP_ENCAP_ESPINUDP) {
--              if (family == AF_INET)
--                      WRITE_ONCE(udp_sk(sk)->gro_receive, xfrm4_gro_udp_encap_rcv);
--              else if (IS_ENABLED(CONFIG_IPV6) && family == AF_INET6)
--                      WRITE_ONCE(udp_sk(sk)->gro_receive, ipv6_stub->xfrm6_gro_udp_encap_rcv);
-+              if (IS_ENABLED(CONFIG_IPV6) && family == AF_INET6)
-+                      new_gro_receive = ipv6_stub->xfrm6_gro_udp_encap_rcv;
-+              else
-+                      new_gro_receive = xfrm4_gro_udp_encap_rcv;
-+
-+              if (udp_sk(sk)->gro_receive != new_gro_receive) {
-+                      /*
-+                       * With IPV6_ADDRFORM the gro callback could change
-+                       * after being set, unregister the old one, if valid.
-+                       */
-+                      if (udp_sk(sk)->gro_receive)
-+                              udp_tunnel_update_gro_rcv(sk, false);
-+
-+                      WRITE_ONCE(udp_sk(sk)->gro_receive, new_gro_receive);
-+                      udp_tunnel_update_gro_rcv(sk, true);
-+              }
-       }
- #endif
- }
-@@ -2962,6 +2980,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
-               break;
-       case UDP_ENCAP:
-+              sockopt_lock_sock(sk);
-               switch (val) {
-               case 0:
- #ifdef CONFIG_XFRM
-@@ -2985,6 +3004,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
-                       err = -ENOPROTOOPT;
-                       break;
-               }
-+              sockopt_release_sock(sk);
-               break;
-       case UDP_NO_CHECK6_TX:
-@@ -3002,13 +3022,14 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
-               break;
-       case UDP_GRO:
--
-+              sockopt_lock_sock(sk);
-               /* when enabling GRO, accept the related GSO packet type */
-               if (valbool)
-                       udp_tunnel_encap_enable(sk);
-               udp_assign_bit(GRO_ENABLED, sk, valbool);
-               udp_assign_bit(ACCEPT_L4, sk, valbool);
-               set_xfrm_gro_udp_encap_rcv(up->encap_type, sk->sk_family, sk);
-+              sockopt_release_sock(sk);
-               break;
-       /*
-diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c
-index 3d1214e6df0ea..2326548997d3f 100644
---- a/net/ipv4/udp_tunnel_core.c
-+++ b/net/ipv4/udp_tunnel_core.c
-@@ -90,6 +90,8 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
-       udp_tunnel_encap_enable(sk);
-+      udp_tunnel_update_gro_rcv(sk, true);
-+
-       if (!sk->sk_dport && !sk->sk_bound_dev_if && sk_saddr_any(sk) &&
-           sk->sk_kern_sock)
-               udp_tunnel_update_gro_lookup(net, sk, true);
--- 
-2.39.5
-
diff --git a/queue-6.15/udp_tunnel-create-a-fastpath-gro-lookup.patch b/queue-6.15/udp_tunnel-create-a-fastpath-gro-lookup.patch
deleted file mode 100644 (file)
index 8e2a770..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-From 57f99d8615549a5172faf93150703db31f61f6eb Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 7 Apr 2025 17:45:41 +0200
-Subject: udp_tunnel: create a fastpath GRO lookup.
-
-From: Paolo Abeni <pabeni@redhat.com>
-
-[ Upstream commit a36283e2b683f172aa1760c77325e50b16c0f792 ]
-
-Most UDP tunnels bind a socket to a local port, with ANY address, no
-peer and no interface index specified.
-Additionally it's quite common to have a single tunnel device per
-namespace.
-
-Track in each namespace the UDP tunnel socket respecting the above.
-When only a single one is present, store a reference in the netns.
-
-When such reference is not NULL, UDP tunnel GRO lookup just need to
-match the incoming packet destination port vs the socket local port.
-
-The tunnel socket never sets the reuse[port] flag[s]. When bound to no
-address and interface, no other socket can exist in the same netns
-matching the specified local port.
-
-Matching packets with non-local destination addresses will be
-aggregated, and eventually segmented as needed - no behavior changes
-intended.
-
-Restrict the optimization to kernel sockets only: it covers all the
-relevant use-cases, and user-space owned sockets could be disconnected
-and rebound after setup_udp_tunnel_sock(), breaking the uniqueness
-assumption
-
-Note that the UDP tunnel socket reference is stored into struct
-netns_ipv4 for both IPv4 and IPv6 tunnels. That is intentional to keep
-all the fastpath-related netns fields in the same struct and allow
-cacheline-based optimization. Currently both the IPv4 and IPv6 socket
-pointer share the same cacheline as the `udp_table` field.
-
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Reviewed-by: Willem de Bruijn <willemb@google.com>
-Link: https://patch.msgid.link/41d16bc8d1257d567f9344c445b4ae0b4a91ede4.1744040675.git.pabeni@redhat.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: c26c192c3d48 ("udp: properly deal with xfrm encap and ADDRFORM")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/udp.h        | 16 ++++++++++++++++
- include/net/netns/ipv4.h   | 11 +++++++++++
- include/net/udp.h          |  1 +
- include/net/udp_tunnel.h   | 12 ++++++++++++
- net/ipv4/udp.c             | 13 ++++++++++++-
- net/ipv4/udp_offload.c     | 37 +++++++++++++++++++++++++++++++++++++
- net/ipv4/udp_tunnel_core.c | 13 +++++++++++++
- net/ipv6/udp.c             |  2 ++
- net/ipv6/udp_offload.c     |  5 +++++
- 9 files changed, 109 insertions(+), 1 deletion(-)
-
-diff --git a/include/linux/udp.h b/include/linux/udp.h
-index 0807e21cfec95..895240177f4f4 100644
---- a/include/linux/udp.h
-+++ b/include/linux/udp.h
-@@ -101,6 +101,13 @@ struct udp_sock {
-       /* Cache friendly copy of sk->sk_peek_off >= 0 */
-       bool            peeking_with_offset;
-+
-+      /*
-+       * Accounting for the tunnel GRO fastpath.
-+       * Unprotected by compilers guard, as it uses space available in
-+       * the last UDP socket cacheline.
-+       */
-+      struct hlist_node       tunnel_list;
- };
- #define udp_test_bit(nr, sk)                  \
-@@ -219,4 +226,13 @@ static inline void udp_allow_gso(struct sock *sk)
- #define IS_UDPLITE(__sk) (__sk->sk_protocol == IPPROTO_UDPLITE)
-+static inline struct sock *udp_tunnel_sk(const struct net *net, bool is_ipv6)
-+{
-+#if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
-+      return rcu_dereference(net->ipv4.udp_tunnel_gro[is_ipv6].sk);
-+#else
-+      return NULL;
-+#endif
-+}
-+
- #endif        /* _LINUX_UDP_H */
-diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
-index 650b2dc9199f4..6373e3f17da84 100644
---- a/include/net/netns/ipv4.h
-+++ b/include/net/netns/ipv4.h
-@@ -47,6 +47,11 @@ struct sysctl_fib_multipath_hash_seed {
- };
- #endif
-+struct udp_tunnel_gro {
-+      struct sock __rcu *sk;
-+      struct hlist_head list;
-+};
-+
- struct netns_ipv4 {
-       /* Cacheline organization can be found documented in
-        * Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst.
-@@ -85,6 +90,11 @@ struct netns_ipv4 {
-       struct inet_timewait_death_row tcp_death_row;
-       struct udp_table *udp_table;
-+#if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
-+      /* Not in a pernet subsys because need to be available at GRO stage */
-+      struct udp_tunnel_gro udp_tunnel_gro[2];
-+#endif
-+
- #ifdef CONFIG_SYSCTL
-       struct ctl_table_header *forw_hdr;
-       struct ctl_table_header *frags_hdr;
-@@ -277,4 +287,5 @@ struct netns_ipv4 {
-       struct hlist_head       *inet_addr_lst;
-       struct delayed_work     addr_chk_work;
- };
-+
- #endif
-diff --git a/include/net/udp.h b/include/net/udp.h
-index 6e89520e100dc..a772510b2aa58 100644
---- a/include/net/udp.h
-+++ b/include/net/udp.h
-@@ -290,6 +290,7 @@ static inline void udp_lib_init_sock(struct sock *sk)
-       struct udp_sock *up = udp_sk(sk);
-       skb_queue_head_init(&up->reader_queue);
-+      INIT_HLIST_NODE(&up->tunnel_list);
-       up->forward_threshold = sk->sk_rcvbuf >> 2;
-       set_bit(SOCK_CUSTOM_SOCKOPT, &sk->sk_socket->flags);
- }
-diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
-index a93dc51f6323e..1bb2b852e90eb 100644
---- a/include/net/udp_tunnel.h
-+++ b/include/net/udp_tunnel.h
-@@ -191,6 +191,18 @@ static inline int udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum)
- }
- #endif
-+#if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
-+void udp_tunnel_update_gro_lookup(struct net *net, struct sock *sk, bool add);
-+#else
-+static inline void udp_tunnel_update_gro_lookup(struct net *net,
-+                                              struct sock *sk, bool add) {}
-+#endif
-+
-+static inline void udp_tunnel_cleanup_gro(struct sock *sk)
-+{
-+      udp_tunnel_update_gro_lookup(sock_net(sk), sk, false);
-+}
-+
- static inline void udp_tunnel_encap_enable(struct sock *sk)
- {
-       if (udp_test_and_set_bit(ENCAP_ENABLED, sk))
-diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
-index 2742cc7602bb5..04cd3353f1d46 100644
---- a/net/ipv4/udp.c
-+++ b/net/ipv4/udp.c
-@@ -2897,8 +2897,10 @@ void udp_destroy_sock(struct sock *sk)
-                       if (encap_destroy)
-                               encap_destroy(sk);
-               }
--              if (udp_test_bit(ENCAP_ENABLED, sk))
-+              if (udp_test_bit(ENCAP_ENABLED, sk)) {
-                       static_branch_dec(&udp_encap_needed_key);
-+                      udp_tunnel_cleanup_gro(sk);
-+              }
-       }
- }
-@@ -3810,6 +3812,15 @@ static void __net_init udp_set_table(struct net *net)
- static int __net_init udp_pernet_init(struct net *net)
- {
-+#if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
-+      int i;
-+
-+      /* No tunnel is configured */
-+      for (i = 0; i < ARRAY_SIZE(net->ipv4.udp_tunnel_gro); ++i) {
-+              INIT_HLIST_HEAD(&net->ipv4.udp_tunnel_gro[i].list);
-+              RCU_INIT_POINTER(net->ipv4.udp_tunnel_gro[i].sk, NULL);
-+      }
-+#endif
-       udp_sysctl_init(net);
-       udp_set_table(net);
-diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
-index 9a8142ccbabe4..67641945ba3a3 100644
---- a/net/ipv4/udp_offload.c
-+++ b/net/ipv4/udp_offload.c
-@@ -12,6 +12,38 @@
- #include <net/udp.h>
- #include <net/protocol.h>
- #include <net/inet_common.h>
-+#include <net/udp_tunnel.h>
-+
-+#if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
-+static DEFINE_SPINLOCK(udp_tunnel_gro_lock);
-+
-+void udp_tunnel_update_gro_lookup(struct net *net, struct sock *sk, bool add)
-+{
-+      bool is_ipv6 = sk->sk_family == AF_INET6;
-+      struct udp_sock *tup, *up = udp_sk(sk);
-+      struct udp_tunnel_gro *udp_tunnel_gro;
-+
-+      spin_lock(&udp_tunnel_gro_lock);
-+      udp_tunnel_gro = &net->ipv4.udp_tunnel_gro[is_ipv6];
-+      if (add)
-+              hlist_add_head(&up->tunnel_list, &udp_tunnel_gro->list);
-+      else if (up->tunnel_list.pprev)
-+              hlist_del_init(&up->tunnel_list);
-+
-+      if (udp_tunnel_gro->list.first &&
-+          !udp_tunnel_gro->list.first->next) {
-+              tup = hlist_entry(udp_tunnel_gro->list.first, struct udp_sock,
-+                                tunnel_list);
-+
-+              rcu_assign_pointer(udp_tunnel_gro->sk, (struct sock *)tup);
-+      } else {
-+              RCU_INIT_POINTER(udp_tunnel_gro->sk, NULL);
-+      }
-+
-+      spin_unlock(&udp_tunnel_gro_lock);
-+}
-+EXPORT_SYMBOL_GPL(udp_tunnel_update_gro_lookup);
-+#endif
- static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
-       netdev_features_t features,
-@@ -694,8 +726,13 @@ static struct sock *udp4_gro_lookup_skb(struct sk_buff *skb, __be16 sport,
- {
-       const struct iphdr *iph = skb_gro_network_header(skb);
-       struct net *net = dev_net_rcu(skb->dev);
-+      struct sock *sk;
-       int iif, sdif;
-+      sk = udp_tunnel_sk(net, false);
-+      if (sk && dport == htons(sk->sk_num))
-+              return sk;
-+
-       inet_get_iif_sdif(skb, &iif, &sdif);
-       return __udp4_lib_lookup(net, iph->saddr, sport,
-diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c
-index 619a53eb672da..3d1214e6df0ea 100644
---- a/net/ipv4/udp_tunnel_core.c
-+++ b/net/ipv4/udp_tunnel_core.c
-@@ -58,6 +58,15 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
- }
- EXPORT_SYMBOL(udp_sock_create4);
-+static bool sk_saddr_any(struct sock *sk)
-+{
-+#if IS_ENABLED(CONFIG_IPV6)
-+      return ipv6_addr_any(&sk->sk_v6_rcv_saddr);
-+#else
-+      return !sk->sk_rcv_saddr;
-+#endif
-+}
-+
- void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
-                          struct udp_tunnel_sock_cfg *cfg)
- {
-@@ -80,6 +89,10 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
-       udp_sk(sk)->gro_complete = cfg->gro_complete;
-       udp_tunnel_encap_enable(sk);
-+
-+      if (!sk->sk_dport && !sk->sk_bound_dev_if && sk_saddr_any(sk) &&
-+          sk->sk_kern_sock)
-+              udp_tunnel_update_gro_lookup(net, sk, true);
- }
- EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock);
-diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
-index 024458ef163c9..7317f8e053f1c 100644
---- a/net/ipv6/udp.c
-+++ b/net/ipv6/udp.c
-@@ -46,6 +46,7 @@
- #include <net/tcp_states.h>
- #include <net/ip6_checksum.h>
- #include <net/ip6_tunnel.h>
-+#include <net/udp_tunnel.h>
- #include <net/xfrm.h>
- #include <net/inet_hashtables.h>
- #include <net/inet6_hashtables.h>
-@@ -1825,6 +1826,7 @@ void udpv6_destroy_sock(struct sock *sk)
-               if (udp_test_bit(ENCAP_ENABLED, sk)) {
-                       static_branch_dec(&udpv6_encap_needed_key);
-                       udp_encap_disable();
-+                      udp_tunnel_cleanup_gro(sk);
-               }
-       }
- }
-diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
-index 404212dfc99ab..d8445ac1b2e43 100644
---- a/net/ipv6/udp_offload.c
-+++ b/net/ipv6/udp_offload.c
-@@ -118,8 +118,13 @@ static struct sock *udp6_gro_lookup_skb(struct sk_buff *skb, __be16 sport,
- {
-       const struct ipv6hdr *iph = skb_gro_network_header(skb);
-       struct net *net = dev_net_rcu(skb->dev);
-+      struct sock *sk;
-       int iif, sdif;
-+      sk = udp_tunnel_sk(net, true);
-+      if (sk && dport == htons(sk->sk_num))
-+              return sk;
-+
-       inet6_get_iif_sdif(skb, &iif, &sdif);
-       return __udp6_lib_lookup(net, &iph->saddr, sport,
--- 
-2.39.5
-
diff --git a/queue-6.15/udp_tunnel-use-static-call-for-gro-hooks-when-possib.patch b/queue-6.15/udp_tunnel-use-static-call-for-gro-hooks-when-possib.patch
deleted file mode 100644 (file)
index a981a37..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-From ad8d1ce2b68078680a685515600fbafbb35fa691 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 7 Apr 2025 17:45:42 +0200
-Subject: udp_tunnel: use static call for GRO hooks when possible
-
-From: Paolo Abeni <pabeni@redhat.com>
-
-[ Upstream commit 5d7f5b2f6b935517ee5fd8058dc32342a5cba3e1 ]
-
-It's quite common to have a single UDP tunnel type active in the
-whole system. In such a case we can replace the indirect call for
-the UDP tunnel GRO callback with a static call.
-
-Add the related accounting in the control path and switch to static
-call when possible. To keep the code simple use a static array for
-the registered tunnel types, and size such array based on the kernel
-config.
-
-Note that there are valid kernel configurations leading to
-UDP_MAX_TUNNEL_TYPES == 0 even with IS_ENABLED(CONFIG_NET_UDP_TUNNEL),
-Explicitly skip the accounting in such a case, to avoid compile warning
-when accessing "udp_tunnel_gro_types".
-
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Reviewed-by: Willem de Bruijn <willemb@google.com>
-Link: https://patch.msgid.link/53d156cdfddcc9678449e873cc83e68fa1582653.1744040675.git.pabeni@redhat.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: c26c192c3d48 ("udp: properly deal with xfrm encap and ADDRFORM")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/net/udp_tunnel.h |   4 ++
- net/ipv4/udp_offload.c   | 135 ++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 138 insertions(+), 1 deletion(-)
-
-diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
-index 1bb2b852e90eb..288f06f23a804 100644
---- a/include/net/udp_tunnel.h
-+++ b/include/net/udp_tunnel.h
-@@ -193,13 +193,16 @@ static inline int udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum)
- #if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
- void udp_tunnel_update_gro_lookup(struct net *net, struct sock *sk, bool add);
-+void udp_tunnel_update_gro_rcv(struct sock *sk, bool add);
- #else
- static inline void udp_tunnel_update_gro_lookup(struct net *net,
-                                               struct sock *sk, bool add) {}
-+static inline void udp_tunnel_update_gro_rcv(struct sock *sk, bool add) {}
- #endif
- static inline void udp_tunnel_cleanup_gro(struct sock *sk)
- {
-+      udp_tunnel_update_gro_rcv(sk, false);
-       udp_tunnel_update_gro_lookup(sock_net(sk), sk, false);
- }
-@@ -212,6 +215,7 @@ static inline void udp_tunnel_encap_enable(struct sock *sk)
-       if (READ_ONCE(sk->sk_family) == PF_INET6)
-               ipv6_stub->udpv6_encap_enable();
- #endif
-+      udp_tunnel_update_gro_rcv(sk, true);
-       udp_encap_enable();
- }
-diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
-index 67641945ba3a3..9c775f8aa4385 100644
---- a/net/ipv4/udp_offload.c
-+++ b/net/ipv4/udp_offload.c
-@@ -15,6 +15,38 @@
- #include <net/udp_tunnel.h>
- #if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
-+
-+/*
-+ * Dummy GRO tunnel callback, exists mainly to avoid dangling/NULL
-+ * values for the udp tunnel static call.
-+ */
-+static struct sk_buff *dummy_gro_rcv(struct sock *sk,
-+                                   struct list_head *head,
-+                                   struct sk_buff *skb)
-+{
-+      NAPI_GRO_CB(skb)->flush = 1;
-+      return NULL;
-+}
-+
-+typedef struct sk_buff *(*udp_tunnel_gro_rcv_t)(struct sock *sk,
-+                                              struct list_head *head,
-+                                              struct sk_buff *skb);
-+
-+struct udp_tunnel_type_entry {
-+      udp_tunnel_gro_rcv_t gro_receive;
-+      refcount_t count;
-+};
-+
-+#define UDP_MAX_TUNNEL_TYPES (IS_ENABLED(CONFIG_GENEVE) + \
-+                            IS_ENABLED(CONFIG_VXLAN) * 2 + \
-+                            IS_ENABLED(CONFIG_NET_FOU) * 2 + \
-+                            IS_ENABLED(CONFIG_XFRM) * 2)
-+
-+DEFINE_STATIC_CALL(udp_tunnel_gro_rcv, dummy_gro_rcv);
-+static DEFINE_STATIC_KEY_FALSE(udp_tunnel_static_call);
-+static struct mutex udp_tunnel_gro_type_lock;
-+static struct udp_tunnel_type_entry udp_tunnel_gro_types[UDP_MAX_TUNNEL_TYPES];
-+static unsigned int udp_tunnel_gro_type_nr;
- static DEFINE_SPINLOCK(udp_tunnel_gro_lock);
- void udp_tunnel_update_gro_lookup(struct net *net, struct sock *sk, bool add)
-@@ -43,6 +75,105 @@ void udp_tunnel_update_gro_lookup(struct net *net, struct sock *sk, bool add)
-       spin_unlock(&udp_tunnel_gro_lock);
- }
- EXPORT_SYMBOL_GPL(udp_tunnel_update_gro_lookup);
-+
-+void udp_tunnel_update_gro_rcv(struct sock *sk, bool add)
-+{
-+      struct udp_tunnel_type_entry *cur = NULL;
-+      struct udp_sock *up = udp_sk(sk);
-+      int i, old_gro_type_nr;
-+
-+      if (!UDP_MAX_TUNNEL_TYPES || !up->gro_receive)
-+              return;
-+
-+      mutex_lock(&udp_tunnel_gro_type_lock);
-+
-+      /* Check if the static call is permanently disabled. */
-+      if (udp_tunnel_gro_type_nr > UDP_MAX_TUNNEL_TYPES)
-+              goto out;
-+
-+      for (i = 0; i < udp_tunnel_gro_type_nr; i++)
-+              if (udp_tunnel_gro_types[i].gro_receive == up->gro_receive)
-+                      cur = &udp_tunnel_gro_types[i];
-+
-+      old_gro_type_nr = udp_tunnel_gro_type_nr;
-+      if (add) {
-+              /*
-+               * Update the matching entry, if found, or add a new one
-+               * if needed
-+               */
-+              if (cur) {
-+                      refcount_inc(&cur->count);
-+                      goto out;
-+              }
-+
-+              if (unlikely(udp_tunnel_gro_type_nr == UDP_MAX_TUNNEL_TYPES)) {
-+                      pr_err_once("Too many UDP tunnel types, please increase UDP_MAX_TUNNEL_TYPES\n");
-+                      /* Ensure static call will never be enabled */
-+                      udp_tunnel_gro_type_nr = UDP_MAX_TUNNEL_TYPES + 1;
-+              } else {
-+                      cur = &udp_tunnel_gro_types[udp_tunnel_gro_type_nr++];
-+                      refcount_set(&cur->count, 1);
-+                      cur->gro_receive = up->gro_receive;
-+              }
-+      } else {
-+              /*
-+               * The stack cleanups only successfully added tunnel, the
-+               * lookup on removal should never fail.
-+               */
-+              if (WARN_ON_ONCE(!cur))
-+                      goto out;
-+
-+              if (!refcount_dec_and_test(&cur->count))
-+                      goto out;
-+
-+              /* Avoid gaps, so that the enable tunnel has always id 0 */
-+              *cur = udp_tunnel_gro_types[--udp_tunnel_gro_type_nr];
-+      }
-+
-+      if (udp_tunnel_gro_type_nr == 1) {
-+              static_call_update(udp_tunnel_gro_rcv,
-+                                 udp_tunnel_gro_types[0].gro_receive);
-+              static_branch_enable(&udp_tunnel_static_call);
-+      } else if (old_gro_type_nr == 1) {
-+              static_branch_disable(&udp_tunnel_static_call);
-+              static_call_update(udp_tunnel_gro_rcv, dummy_gro_rcv);
-+      }
-+
-+out:
-+      mutex_unlock(&udp_tunnel_gro_type_lock);
-+}
-+EXPORT_SYMBOL_GPL(udp_tunnel_update_gro_rcv);
-+
-+static void udp_tunnel_gro_init(void)
-+{
-+      mutex_init(&udp_tunnel_gro_type_lock);
-+}
-+
-+static struct sk_buff *udp_tunnel_gro_rcv(struct sock *sk,
-+                                        struct list_head *head,
-+                                        struct sk_buff *skb)
-+{
-+      if (static_branch_likely(&udp_tunnel_static_call)) {
-+              if (unlikely(gro_recursion_inc_test(skb))) {
-+                      NAPI_GRO_CB(skb)->flush |= 1;
-+                      return NULL;
-+              }
-+              return static_call(udp_tunnel_gro_rcv)(sk, head, skb);
-+      }
-+      return call_gro_receive_sk(udp_sk(sk)->gro_receive, sk, head, skb);
-+}
-+
-+#else
-+
-+static void udp_tunnel_gro_init(void) {}
-+
-+static struct sk_buff *udp_tunnel_gro_rcv(struct sock *sk,
-+                                        struct list_head *head,
-+                                        struct sk_buff *skb)
-+{
-+      return call_gro_receive_sk(udp_sk(sk)->gro_receive, sk, head, skb);
-+}
-+
- #endif
- static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
-@@ -713,7 +844,7 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
-       skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */
-       skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr));
--      pp = call_gro_receive_sk(udp_sk(sk)->gro_receive, sk, head, skb);
-+      pp = udp_tunnel_gro_rcv(sk, head, skb);
- out:
-       skb_gro_flush_final(skb, pp, flush);
-@@ -863,5 +994,7 @@ int __init udpv4_offload_init(void)
-                       .gro_complete = udp4_gro_complete,
-               },
-       };
-+
-+      udp_tunnel_gro_init();
-       return inet_add_offload(&net_hotdata.udpv4_offload, IPPROTO_UDP);
- }
--- 
-2.39.5
-