From: Greg Kroah-Hartman Date: Tue, 12 Sep 2023 12:03:52 +0000 (+0200) Subject: drop a bunch of networking patches from queues X-Git-Tag: v6.1.53~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bc506e756c597cd54e1db319fb5a25506cc07073;p=thirdparty%2Fkernel%2Fstable-queue.git drop a bunch of networking patches from queues --- diff --git a/queue-5.15/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch b/queue-5.15/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch deleted file mode 100644 index cacfc03c641..00000000000 --- a/queue-5.15/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch +++ /dev/null @@ -1,332 +0,0 @@ -From 6ce9726cde011d60974f784cd8e849820b062de2 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:11 +0200 -Subject: bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign - -From: Lorenz Bauer - -[ Upstream commit 9c02bec95954252c3c01bfbb3f7560e0b95ca955 ] - -Currently the bpf_sk_assign helper in tc BPF context refuses SO_REUSEPORT -sockets. This means we can't use the helper to steer traffic to Envoy, -which configures SO_REUSEPORT on its sockets. In turn, we're blocked -from removing TPROXY from our setup. - -The reason that bpf_sk_assign refuses such sockets is that the -bpf_sk_lookup helpers don't execute SK_REUSEPORT programs. Instead, -one of the reuseport sockets is selected by hash. This could cause -dispatch to the "wrong" socket: - - sk = bpf_sk_lookup_tcp(...) // select SO_REUSEPORT by hash - bpf_sk_assign(skb, sk) // SK_REUSEPORT wasn't executed - -Fixing this isn't as simple as invoking SK_REUSEPORT from the lookup -helpers unfortunately. In the tc context, L2 headers are at the start -of the skb, while SK_REUSEPORT expects L3 headers instead. - -Instead, we execute the SK_REUSEPORT program when the assigned socket -is pulled out of the skb, further up the stack. This creates some -trickiness with regards to refcounting as bpf_sk_assign will put both -refcounted and RCU freed sockets in skb->sk. reuseport sockets are RCU -freed. We can infer that the sk_assigned socket is RCU freed if the -reuseport lookup succeeds, but convincing yourself of this fact isn't -straight forward. Therefore we defensively check refcounting on the -sk_assign sock even though it's probably not required in practice. - -Fixes: 8e368dc72e86 ("bpf: Fix use of sk->sk_reuseport from sk_assign") -Fixes: cf7fbe660f2d ("bpf: Add socket assign support") -Co-developed-by: Daniel Borkmann -Signed-off-by: Daniel Borkmann -Cc: Joe Stringer -Link: https://lore.kernel.org/bpf/CACAyw98+qycmpQzKupquhkxbvWK4OFyDuuLMBNROnfWMZxUWeA@mail.gmail.com/ -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-7-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 56 +++++++++++++++++++++++++++++++--- - include/net/inet_hashtables.h | 49 +++++++++++++++++++++++++++-- - include/net/sock.h | 7 +++-- - include/uapi/linux/bpf.h | 3 -- - net/core/filter.c | 2 -- - net/ipv4/udp.c | 8 +++-- - net/ipv6/udp.c | 8 +++-- - tools/include/uapi/linux/bpf.h | 3 -- - 8 files changed, 115 insertions(+), 21 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index f89320b6fee31..475e672b4facc 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -94,6 +94,46 @@ static inline struct sock *__inet6_lookup(struct net *net, - daddr, hnum, dif, sdif); - } - -+static inline -+struct sock *inet6_steal_sock(struct net *net, struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, const __be16 sport, -+ const struct in6_addr *daddr, const __be16 dport, -+ bool *refcounted, inet6_ehashfn_t *ehashfn) -+{ -+ struct sock *sk, *reuse_sk; -+ bool prefetched; -+ -+ sk = skb_steal_sock(skb, refcounted, &prefetched); -+ if (!sk) -+ return NULL; -+ -+ if (!prefetched) -+ return sk; -+ -+ if (sk->sk_protocol == IPPROTO_TCP) { -+ if (sk->sk_state != TCP_LISTEN) -+ return sk; -+ } else if (sk->sk_protocol == IPPROTO_UDP) { -+ if (sk->sk_state != TCP_CLOSE) -+ return sk; -+ } else { -+ return sk; -+ } -+ -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, ntohs(dport), -+ ehashfn); -+ if (!reuse_sk) -+ return sk; -+ -+ /* We've chosen a new reuseport sock which is never refcounted. This -+ * implies that sk also isn't refcounted. -+ */ -+ WARN_ON_ONCE(*refcounted); -+ -+ return reuse_sk; -+} -+ - static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, - struct sk_buff *skb, int doff, - const __be16 sport, -@@ -101,14 +141,20 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, - int iif, int sdif, - bool *refcounted) - { -- struct sock *sk = skb_steal_sock(skb, refcounted); -- -+ struct net *net = dev_net(skb_dst(skb)->dev); -+ const struct ipv6hdr *ip6h = ipv6_hdr(skb); -+ struct sock *sk; -+ -+ sk = inet6_steal_sock(net, skb, doff, &ip6h->saddr, sport, &ip6h->daddr, dport, -+ refcounted, inet6_ehashfn); -+ if (IS_ERR(sk)) -+ return NULL; - if (sk) - return sk; - -- return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, -- doff, &ipv6_hdr(skb)->saddr, sport, -- &ipv6_hdr(skb)->daddr, ntohs(dport), -+ return __inet6_lookup(net, hashinfo, skb, -+ doff, &ip6h->saddr, sport, -+ &ip6h->daddr, ntohs(dport), - iif, sdif, refcounted); - } - -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index f4b4102744a50..06f1ab600481e 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -382,6 +382,46 @@ static inline struct sock *inet_lookup(struct net *net, - return sk; - } - -+static inline -+struct sock *inet_steal_sock(struct net *net, struct sk_buff *skb, int doff, -+ const __be32 saddr, const __be16 sport, -+ const __be32 daddr, const __be16 dport, -+ bool *refcounted, inet_ehashfn_t *ehashfn) -+{ -+ struct sock *sk, *reuse_sk; -+ bool prefetched; -+ -+ sk = skb_steal_sock(skb, refcounted, &prefetched); -+ if (!sk) -+ return NULL; -+ -+ if (!prefetched) -+ return sk; -+ -+ if (sk->sk_protocol == IPPROTO_TCP) { -+ if (sk->sk_state != TCP_LISTEN) -+ return sk; -+ } else if (sk->sk_protocol == IPPROTO_UDP) { -+ if (sk->sk_state != TCP_CLOSE) -+ return sk; -+ } else { -+ return sk; -+ } -+ -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, ntohs(dport), -+ ehashfn); -+ if (!reuse_sk) -+ return sk; -+ -+ /* We've chosen a new reuseport sock which is never refcounted. This -+ * implies that sk also isn't refcounted. -+ */ -+ WARN_ON_ONCE(*refcounted); -+ -+ return reuse_sk; -+} -+ - static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - struct sk_buff *skb, - int doff, -@@ -390,13 +430,18 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - const int sdif, - bool *refcounted) - { -- struct sock *sk = skb_steal_sock(skb, refcounted); -+ struct net *net = dev_net(skb_dst(skb)->dev); - const struct iphdr *iph = ip_hdr(skb); -+ struct sock *sk; - -+ sk = inet_steal_sock(net, skb, doff, iph->saddr, sport, iph->daddr, dport, -+ refcounted, inet_ehashfn); -+ if (IS_ERR(sk)) -+ return NULL; - if (sk) - return sk; - -- return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, -+ return __inet_lookup(net, hashinfo, skb, - doff, iph->saddr, sport, - iph->daddr, dport, inet_iif(skb), sdif, - refcounted); -diff --git a/include/net/sock.h b/include/net/sock.h -index 640bd7a367779..68579cb022e25 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -2745,20 +2745,23 @@ sk_is_refcounted(struct sock *sk) - * skb_steal_sock - steal a socket from an sk_buff - * @skb: sk_buff to steal the socket from - * @refcounted: is set to true if the socket is reference-counted -+ * @prefetched: is set to true if the socket was assigned from bpf - */ - static inline struct sock * --skb_steal_sock(struct sk_buff *skb, bool *refcounted) -+skb_steal_sock(struct sk_buff *skb, bool *refcounted, bool *prefetched) - { - if (skb->sk) { - struct sock *sk = skb->sk; - - *refcounted = true; -- if (skb_sk_is_prefetched(skb)) -+ *prefetched = skb_sk_is_prefetched(skb); -+ if (*prefetched) - *refcounted = sk_is_refcounted(sk); - skb->destructor = NULL; - skb->sk = NULL; - return sk; - } -+ *prefetched = false; - *refcounted = false; - return NULL; - } -diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h -index a887e582f0e78..b9c5a942bc545 100644 ---- a/include/uapi/linux/bpf.h -+++ b/include/uapi/linux/bpf.h -@@ -3976,9 +3976,6 @@ union bpf_attr { - * **-EOPNOTSUPP** if the operation is not supported, for example - * a call from outside of TC ingress. - * -- * **-ESOCKTNOSUPPORT** if the socket type is not supported -- * (reuseport). -- * - * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags) - * Description - * Helper is overloaded depending on BPF program type. This -diff --git a/net/core/filter.c b/net/core/filter.c -index 76432aa3b717c..6f1fab853e77e 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -6957,8 +6957,6 @@ BPF_CALL_3(bpf_sk_assign, struct sk_buff *, skb, struct sock *, sk, u64, flags) - return -EOPNOTSUPP; - if (unlikely(dev_net(skb->dev) != sock_net(sk))) - return -ENETUNREACH; -- if (unlikely(sk_fullsock(sk) && sk->sk_reuseport)) -- return -ESOCKTNOSUPPORT; - if (sk_unhashed(sk)) - return -EOPNOTSUPP; - if (sk_is_refcounted(sk) && -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index de672235ceee5..9149b7aeddc65 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -2446,7 +2446,11 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - if (udp4_csum_init(skb, uh, proto)) - goto csum_error; - -- sk = skb_steal_sock(skb, &refcounted); -+ sk = inet_steal_sock(net, skb, sizeof(struct udphdr), saddr, uh->source, daddr, uh->dest, -+ &refcounted, udp_ehashfn); -+ if (IS_ERR(sk)) -+ goto no_sk; -+ - if (sk) { - struct dst_entry *dst = skb_dst(skb); - int ret; -@@ -2467,7 +2471,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable); - if (sk) - return udp_unicast_rcv_skb(sk, skb, uh); -- -+no_sk: - if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) - goto drop; - nf_reset_ct(skb); -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index 2c653ed1add1f..04dfc16425de9 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -969,7 +969,11 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - goto csum_error; - - /* Check if the socket is already available, e.g. due to early demux */ -- sk = skb_steal_sock(skb, &refcounted); -+ sk = inet6_steal_sock(net, skb, sizeof(struct udphdr), saddr, uh->source, daddr, uh->dest, -+ &refcounted, udp6_ehashfn); -+ if (IS_ERR(sk)) -+ goto no_sk; -+ - if (sk) { - struct dst_entry *dst = skb_dst(skb); - int ret; -@@ -1003,7 +1007,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - goto report_csum_error; - return udp6_unicast_rcv_skb(sk, skb, uh); - } -- -+no_sk: - reason = SKB_DROP_REASON_NO_SOCKET; - - if (!uh->check) -diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h -index 8330e3ca8fbfb..39a209c4c65c4 100644 ---- a/tools/include/uapi/linux/bpf.h -+++ b/tools/include/uapi/linux/bpf.h -@@ -3976,9 +3976,6 @@ union bpf_attr { - * **-EOPNOTSUPP** if the operation is not supported, for example - * a call from outside of TC ingress. - * -- * **-ESOCKTNOSUPPORT** if the socket type is not supported -- * (reuseport). -- * - * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags) - * Description - * Helper is overloaded depending on BPF program type. This --- -2.40.1 - diff --git a/queue-5.15/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch b/queue-5.15/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch deleted file mode 100644 index 3d75d9c4e70..00000000000 --- a/queue-5.15/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 9b7d85edbdcc2fbbf712f90893ba61c2e99134d0 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:07 +0200 -Subject: net: export inet_lookup_reuseport and inet6_lookup_reuseport - -From: Lorenz Bauer - -[ Upstream commit ce796e60b3b196b61fcc565df195443cbb846ef0 ] - -Rename the existing reuseport helpers for IPv4 and IPv6 so that they -can be invoked in the follow up commit. Export them so that building -DCCP and IPv6 as a module works. - -No change in functionality. - -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-3-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Stable-dep-of: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 7 +++++++ - include/net/inet_hashtables.h | 5 +++++ - net/ipv4/inet_hashtables.c | 15 ++++++++------- - net/ipv6/inet6_hashtables.c | 19 ++++++++++--------- - 4 files changed, 30 insertions(+), 16 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 56f1286583d3c..032ddab48f8f8 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -48,6 +48,13 @@ struct sock *__inet6_lookup_established(struct net *net, - const u16 hnum, const int dif, - const int sdif); - -+struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, -+ __be16 sport, -+ const struct in6_addr *daddr, -+ unsigned short hnum); -+ - struct sock *inet6_lookup_listener(struct net *net, - struct inet_hashinfo *hashinfo, - struct sk_buff *skb, int doff, -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index 53c22b64e9724..6c7606b5cadfd 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -319,6 +319,11 @@ struct sock *__inet_lookup_established(struct net *net, - const __be32 daddr, const u16 hnum, - const int dif, const int sdif); - -+struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ __be32 saddr, __be16 sport, -+ __be32 daddr, unsigned short hnum); -+ - static inline struct sock * - inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, - const __be32 saddr, const __be16 sport, -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index 2936676f86eb8..ce32401567647 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -252,10 +252,10 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - --static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, int doff, -- __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) -+struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ __be32 saddr, __be16 sport, -+ __be32 daddr, unsigned short hnum) - { - struct sock *reuse_sk = NULL; - u32 phash; -@@ -266,6 +266,7 @@ static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, - } - return reuse_sk; - } -+EXPORT_SYMBOL_GPL(inet_lookup_reuseport); - - /* - * Here are some nice properties to exploit here. The BSD API -@@ -290,8 +291,8 @@ static struct sock *inet_lhash2_lookup(struct net *net, - sk = (struct sock *)icsk; - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { -- result = lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ result = inet_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum); - if (result) - return result; - -@@ -320,7 +321,7 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c -index b4a5e01e12016..2267f973e2df3 100644 ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -113,12 +113,12 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - --static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, int doff, -- const struct in6_addr *saddr, -- __be16 sport, -- const struct in6_addr *daddr, -- unsigned short hnum) -+struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, -+ __be16 sport, -+ const struct in6_addr *daddr, -+ unsigned short hnum) - { - struct sock *reuse_sk = NULL; - u32 phash; -@@ -129,6 +129,7 @@ static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, - } - return reuse_sk; - } -+EXPORT_SYMBOL_GPL(inet6_lookup_reuseport); - - /* called with rcu_read_lock() */ - static struct sock *inet6_lhash2_lookup(struct net *net, -@@ -146,8 +147,8 @@ static struct sock *inet6_lhash2_lookup(struct net *net, - sk = (struct sock *)icsk; - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { -- result = lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ result = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum); - if (result) - return result; - -@@ -178,7 +179,7 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); - if (reuse_sk) - sk = reuse_sk; - return sk; --- -2.40.1 - diff --git a/queue-5.15/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch b/queue-5.15/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch deleted file mode 100644 index 45452d0a6fb..00000000000 --- a/queue-5.15/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 430fce638025f2cbeed253cadc4471699844dddb Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 15 Aug 2023 09:53:41 +0100 -Subject: net: Fix slab-out-of-bounds in inet[6]_steal_sock - -From: Lorenz Bauer - -[ Upstream commit 8897562f67b3e61ad736cd5c9f307447d33280e4 ] - -Kumar reported a KASAN splat in tcp_v6_rcv: - - bash-5.2# ./test_progs -t btf_skc_cls_ingress - ... - [ 51.810085] BUG: KASAN: slab-out-of-bounds in tcp_v6_rcv+0x2d7d/0x3440 - [ 51.810458] Read of size 2 at addr ffff8881053f038c by task test_progs/226 - -The problem is that inet[6]_steal_sock accesses sk->sk_protocol without -accounting for request or timewait sockets. To fix this we can't just -check sock_common->skc_reuseport since that flag is present on timewait -sockets. - -Instead, add a fullsock check to avoid the out of bands access of sk_protocol. - -Fixes: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Reported-by: Kumar Kartikeya Dwivedi -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230815-bpf-next-v2-1-95126eaa4c1b@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 2 +- - include/net/inet_hashtables.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 475e672b4facc..12780b8fb5630 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -107,7 +107,7 @@ struct sock *inet6_steal_sock(struct net *net, struct sk_buff *skb, int doff, - if (!sk) - return NULL; - -- if (!prefetched) -+ if (!prefetched || !sk_fullsock(sk)) - return sk; - - if (sk->sk_protocol == IPPROTO_TCP) { -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index 06f1ab600481e..0cc2a88d1c37c 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -395,7 +395,7 @@ struct sock *inet_steal_sock(struct net *net, struct sk_buff *skb, int doff, - if (!sk) - return NULL; - -- if (!prefetched) -+ if (!prefetched || !sk_fullsock(sk)) - return sk; - - if (sk->sk_protocol == IPPROTO_TCP) { --- -2.40.1 - diff --git a/queue-5.15/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch b/queue-5.15/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch deleted file mode 100644 index 675d8570a43..00000000000 --- a/queue-5.15/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 74bdfab4fd7c641e55f7fe9d1be9687eeb01df67 Mon Sep 17 00:00:00 2001 -From: Lorenz Bauer -Date: Mon, 31 Jul 2023 11:42:53 +0200 -Subject: net: remove duplicate INDIRECT_CALLABLE_DECLARE of udp[6]_ehashfn - -From: Lorenz Bauer - -commit 74bdfab4fd7c641e55f7fe9d1be9687eeb01df67 upstream. - -There are already INDIRECT_CALLABLE_DECLARE in the hashtable -headers, no need to declare them again. - -Fixes: 0f495f761722 ("net: remove duplicate reuseport_lookup functions") -Suggested-by: Martin Lau -Signed-off-by: Lorenz Bauer -Reviewed-by: Kuniyuki Iwashima -Link: https://lore.kernel.org/r/20230731-indir-call-v1-1-4cd0aeaee64f@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Greg Kroah-Hartman ---- - net/ipv4/inet_hashtables.c | 2 -- - net/ipv6/inet6_hashtables.c | 2 -- - 2 files changed, 4 deletions(-) - ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -253,8 +253,6 @@ static inline int compute_score(struct s - return score; - } - --INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -- - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -114,8 +114,6 @@ static inline int compute_score(struct s - return score; - } - --INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -- - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, diff --git a/queue-5.15/net-remove-duplicate-reuseport_lookup-functions.patch b/queue-5.15/net-remove-duplicate-reuseport_lookup-functions.patch deleted file mode 100644 index 3b6f2331d7f..00000000000 --- a/queue-5.15/net-remove-duplicate-reuseport_lookup-functions.patch +++ /dev/null @@ -1,365 +0,0 @@ -From 80dd0a17af4bad8ab1687e60f1a0800d59f41fc3 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:08 +0200 -Subject: net: remove duplicate reuseport_lookup functions - -From: Lorenz Bauer - -[ Upstream commit 0f495f7617229772403e683033abc473f0f0553c ] - -There are currently four copies of reuseport_lookup: one each for -(TCP, UDP)x(IPv4, IPv6). This forces us to duplicate all callers of -those functions as well. This is already the case for sk_lookup -helpers (inet,inet6,udp4,udp6)_lookup_run_bpf. - -There are two differences between the reuseport_lookup helpers: - -1. They call different hash functions depending on protocol -2. UDP reuseport_lookup checks that sk_state != TCP_ESTABLISHED - -Move the check for sk_state into the caller and use the INDIRECT_CALL -infrastructure to cut down the helpers to one per IP version. - -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-4-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Stable-dep-of: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 11 ++++++++- - include/net/inet_hashtables.h | 15 ++++++++----- - net/ipv4/inet_hashtables.c | 20 +++++++++++------ - net/ipv4/udp.c | 34 +++++++++++----------------- - net/ipv6/inet6_hashtables.c | 14 ++++++++---- - net/ipv6/udp.c | 41 +++++++++++++--------------------- - 6 files changed, 72 insertions(+), 63 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 032ddab48f8f8..f89320b6fee31 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -48,12 +48,21 @@ struct sock *__inet6_lookup_established(struct net *net, - const u16 hnum, const int dif, - const int sdif); - -+typedef u32 (inet6_ehashfn_t)(const struct net *net, -+ const struct in6_addr *laddr, const u16 lport, -+ const struct in6_addr *faddr, const __be16 fport); -+ -+inet6_ehashfn_t inet6_ehashfn; -+ -+INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -+ - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, - __be16 sport, - const struct in6_addr *daddr, -- unsigned short hnum); -+ unsigned short hnum, -+ inet6_ehashfn_t *ehashfn); - - struct sock *inet6_lookup_listener(struct net *net, - struct inet_hashinfo *hashinfo, -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index 6c7606b5cadfd..f4b4102744a50 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -319,10 +319,19 @@ struct sock *__inet_lookup_established(struct net *net, - const __be32 daddr, const u16 hnum, - const int dif, const int sdif); - -+typedef u32 (inet_ehashfn_t)(const struct net *net, -+ const __be32 laddr, const __u16 lport, -+ const __be32 faddr, const __be16 fport); -+ -+inet_ehashfn_t inet_ehashfn; -+ -+INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -+ - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum); -+ __be32 daddr, unsigned short hnum, -+ inet_ehashfn_t *ehashfn); - - static inline struct sock * - inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, -@@ -393,10 +402,6 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - refcounted); - } - --u32 inet6_ehashfn(const struct net *net, -- const struct in6_addr *laddr, const u16 lport, -- const struct in6_addr *faddr, const __be16 fport); -- - static inline void sk_daddr_set(struct sock *sk, __be32 addr) - { - sk->sk_daddr = addr; /* alias of inet_daddr */ -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index ce32401567647..0b2b652ad4898 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -28,9 +28,9 @@ - #include - #include - --static u32 inet_ehashfn(const struct net *net, const __be32 laddr, -- const __u16 lport, const __be32 faddr, -- const __be16 fport) -+u32 inet_ehashfn(const struct net *net, const __be32 laddr, -+ const __u16 lport, const __be32 faddr, -+ const __be16 fport) - { - static u32 inet_ehash_secret __read_mostly; - -@@ -39,6 +39,7 @@ static u32 inet_ehashfn(const struct net *net, const __be32 laddr, - return __inet_ehashfn(laddr, lport, faddr, fport, - inet_ehash_secret + net_hash_mix(net)); - } -+EXPORT_SYMBOL_GPL(inet_ehashfn); - - /* This function handles inet_sock, but also timewait and request sockets - * for IPv4/IPv6. -@@ -252,16 +253,20 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - -+INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -+ - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) -+ __be32 daddr, unsigned short hnum, -+ inet_ehashfn_t *ehashfn) - { - struct sock *reuse_sk = NULL; - u32 phash; - - if (sk->sk_reuseport) { -- phash = inet_ehashfn(net, daddr, hnum, saddr, sport); -+ phash = INDIRECT_CALL_2(ehashfn, udp_ehashfn, inet_ehashfn, -+ net, daddr, hnum, saddr, sport); - reuse_sk = reuseport_select_sock(sk, phash, skb, doff); - } - return reuse_sk; -@@ -292,7 +297,7 @@ static struct sock *inet_lhash2_lookup(struct net *net, - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { - result = inet_lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ saddr, sport, daddr, hnum, inet_ehashfn); - if (result) - return result; - -@@ -321,7 +326,8 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum, -+ inet_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index 198d8e07413d3..de672235ceee5 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -398,9 +398,9 @@ static int compute_score(struct sock *sk, struct net *net, - return score; - } - --static u32 udp_ehashfn(const struct net *net, const __be32 laddr, -- const __u16 lport, const __be32 faddr, -- const __be16 fport) -+INDIRECT_CALLABLE_SCOPE -+u32 udp_ehashfn(const struct net *net, const __be32 laddr, const __u16 lport, -+ const __be32 faddr, const __be16 fport) - { - static u32 udp_ehash_secret __read_mostly; - -@@ -410,22 +410,6 @@ static u32 udp_ehashfn(const struct net *net, const __be32 laddr, - udp_ehash_secret + net_hash_mix(net)); - } - --static struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, -- __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) --{ -- struct sock *reuse_sk = NULL; -- u32 hash; -- -- if (sk->sk_reuseport && sk->sk_state != TCP_ESTABLISHED) { -- hash = udp_ehashfn(net, daddr, hnum, saddr, sport); -- reuse_sk = reuseport_select_sock(sk, hash, skb, -- sizeof(struct udphdr)); -- } -- return reuse_sk; --} -- - /* called with rcu_read_lock() */ - static struct sock *udp4_lib_lookup2(struct net *net, - __be32 saddr, __be16 sport, -@@ -444,7 +428,14 @@ static struct sock *udp4_lib_lookup2(struct net *net, - daddr, hnum, dif, sdif); - if (score > badness) { - badness = score; -- result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ -+ if (sk->sk_state == TCP_ESTABLISHED) { -+ result = sk; -+ continue; -+ } -+ -+ result = inet_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp_ehashfn); - if (!result) { - result = sk; - continue; -@@ -483,7 +474,8 @@ static struct sock *udp4_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c -index 2267f973e2df3..21b4fc835487b 100644 ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -41,6 +41,7 @@ u32 inet6_ehashfn(const struct net *net, - return __inet6_ehashfn(lhash, lport, fhash, fport, - inet6_ehash_secret + net_hash_mix(net)); - } -+EXPORT_SYMBOL_GPL(inet6_ehashfn); - - /* - * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so -@@ -113,18 +114,22 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - -+INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -+ - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, - __be16 sport, - const struct in6_addr *daddr, -- unsigned short hnum) -+ unsigned short hnum, -+ inet6_ehashfn_t *ehashfn) - { - struct sock *reuse_sk = NULL; - u32 phash; - - if (sk->sk_reuseport) { -- phash = inet6_ehashfn(net, daddr, hnum, saddr, sport); -+ phash = INDIRECT_CALL_INET(ehashfn, udp6_ehashfn, inet6_ehashfn, -+ net, daddr, hnum, saddr, sport); - reuse_sk = reuseport_select_sock(sk, phash, skb, doff); - } - return reuse_sk; -@@ -148,7 +153,7 @@ static struct sock *inet6_lhash2_lookup(struct net *net, - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { - result = inet6_lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ saddr, sport, daddr, hnum, inet6_ehashfn); - if (result) - return result; - -@@ -179,7 +184,8 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum, inet6_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index d5d254ca2dfe6..2c653ed1add1f 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -68,11 +68,12 @@ int udpv6_init_sock(struct sock *sk) - return 0; - } - --static u32 udp6_ehashfn(const struct net *net, -- const struct in6_addr *laddr, -- const u16 lport, -- const struct in6_addr *faddr, -- const __be16 fport) -+INDIRECT_CALLABLE_SCOPE -+u32 udp6_ehashfn(const struct net *net, -+ const struct in6_addr *laddr, -+ const u16 lport, -+ const struct in6_addr *faddr, -+ const __be16 fport) - { - static u32 udp6_ehash_secret __read_mostly; - static u32 udp_ipv6_hash_secret __read_mostly; -@@ -156,24 +157,6 @@ static int compute_score(struct sock *sk, struct net *net, - return score; - } - --static struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, -- const struct in6_addr *saddr, -- __be16 sport, -- const struct in6_addr *daddr, -- unsigned int hnum) --{ -- struct sock *reuse_sk = NULL; -- u32 hash; -- -- if (sk->sk_reuseport && sk->sk_state != TCP_ESTABLISHED) { -- hash = udp6_ehashfn(net, daddr, hnum, saddr, sport); -- reuse_sk = reuseport_select_sock(sk, hash, skb, -- sizeof(struct udphdr)); -- } -- return reuse_sk; --} -- - /* called with rcu_read_lock() */ - static struct sock *udp6_lib_lookup2(struct net *net, - const struct in6_addr *saddr, __be16 sport, -@@ -191,7 +174,14 @@ static struct sock *udp6_lib_lookup2(struct net *net, - daddr, hnum, dif, sdif); - if (score > badness) { - badness = score; -- result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ -+ if (sk->sk_state == TCP_ESTABLISHED) { -+ result = sk; -+ continue; -+ } -+ -+ result = inet6_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp6_ehashfn); - if (!result) { - result = sk; - continue; -@@ -231,7 +221,8 @@ static inline struct sock *udp6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp6_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; --- -2.40.1 - diff --git a/queue-5.15/series b/queue-5.15/series index 0aa6bd55c4f..32c932fb70e 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -85,9 +85,6 @@ regmap-rbtree-use-alloc_flags-for-memory-allocations.patch udp-re-score-reuseport-groups-when-connected-sockets.patch bpf-reject-unhashed-sockets-in-bpf_sk_assign.patch ipv6-add-reasons-for-skb-drops-to-__udp6_lib_rcv.patch -net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch -net-remove-duplicate-reuseport_lookup-functions.patch -bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch wifi-mt76-testmode-add-nla_policy-for-mt76_tm_attr_t.patch spi-tegra20-sflash-fix-to-check-return-value-of-plat.patch can-gs_usb-gs_usb_receive_bulk_callback-count-rx-ove.patch @@ -101,7 +98,6 @@ bluetooth-nokia-fix-value-check-in-nokia_bluetooth_s.patch bluetooth-fix-potential-use-after-free-when-clear-ke.patch net-tcp-fix-unexcepted-socket-die-when-snd_wnd-is-0.patch selftests-bpf-clean-up-fmod_ret-in-bench_rename-test.patch -net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch net-memcg-fix-scope-of-sockmem-pressure-indicators.patch ice-ice_aq_check_events-fix-off-by-one-check-when-fi.patch crypto-caam-fix-unchecked-return-value-error.patch @@ -371,7 +367,6 @@ usb-core-fix-race-by-not-overwriting-udev-descriptor-in-hub_port_init.patch usb-core-fix-oversight-in-superspeed-initialization.patch x86-sgx-break-up-long-non-preemptible-delays-in-sgx_vepc_release.patch perf-x86-uncore-correct-the-number-of-chas-on-emr.patch -net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch tracing-zero-the-pipe-cpumask-on-alloc-to-avoid-spurious-ebusy.patch md-md-bitmap-remove-unnecessary-local-variable-in-backlog_store.patch revert-drm-amdgpu-install-stub-fence-into-potential-unused-fence-pointers.patch diff --git a/queue-6.1/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch b/queue-6.1/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch deleted file mode 100644 index f8953982de3..00000000000 --- a/queue-6.1/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch +++ /dev/null @@ -1,332 +0,0 @@ -From d3beaba9fbe2a4e2efbcc3fbae860410c59e85e7 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:11 +0200 -Subject: bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign - -From: Lorenz Bauer - -[ Upstream commit 9c02bec95954252c3c01bfbb3f7560e0b95ca955 ] - -Currently the bpf_sk_assign helper in tc BPF context refuses SO_REUSEPORT -sockets. This means we can't use the helper to steer traffic to Envoy, -which configures SO_REUSEPORT on its sockets. In turn, we're blocked -from removing TPROXY from our setup. - -The reason that bpf_sk_assign refuses such sockets is that the -bpf_sk_lookup helpers don't execute SK_REUSEPORT programs. Instead, -one of the reuseport sockets is selected by hash. This could cause -dispatch to the "wrong" socket: - - sk = bpf_sk_lookup_tcp(...) // select SO_REUSEPORT by hash - bpf_sk_assign(skb, sk) // SK_REUSEPORT wasn't executed - -Fixing this isn't as simple as invoking SK_REUSEPORT from the lookup -helpers unfortunately. In the tc context, L2 headers are at the start -of the skb, while SK_REUSEPORT expects L3 headers instead. - -Instead, we execute the SK_REUSEPORT program when the assigned socket -is pulled out of the skb, further up the stack. This creates some -trickiness with regards to refcounting as bpf_sk_assign will put both -refcounted and RCU freed sockets in skb->sk. reuseport sockets are RCU -freed. We can infer that the sk_assigned socket is RCU freed if the -reuseport lookup succeeds, but convincing yourself of this fact isn't -straight forward. Therefore we defensively check refcounting on the -sk_assign sock even though it's probably not required in practice. - -Fixes: 8e368dc72e86 ("bpf: Fix use of sk->sk_reuseport from sk_assign") -Fixes: cf7fbe660f2d ("bpf: Add socket assign support") -Co-developed-by: Daniel Borkmann -Signed-off-by: Daniel Borkmann -Cc: Joe Stringer -Link: https://lore.kernel.org/bpf/CACAyw98+qycmpQzKupquhkxbvWK4OFyDuuLMBNROnfWMZxUWeA@mail.gmail.com/ -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-7-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 56 +++++++++++++++++++++++++++++++--- - include/net/inet_hashtables.h | 49 +++++++++++++++++++++++++++-- - include/net/sock.h | 7 +++-- - include/uapi/linux/bpf.h | 3 -- - net/core/filter.c | 2 -- - net/ipv4/udp.c | 8 +++-- - net/ipv6/udp.c | 8 +++-- - tools/include/uapi/linux/bpf.h | 3 -- - 8 files changed, 115 insertions(+), 21 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index f89320b6fee31..475e672b4facc 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -94,6 +94,46 @@ static inline struct sock *__inet6_lookup(struct net *net, - daddr, hnum, dif, sdif); - } - -+static inline -+struct sock *inet6_steal_sock(struct net *net, struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, const __be16 sport, -+ const struct in6_addr *daddr, const __be16 dport, -+ bool *refcounted, inet6_ehashfn_t *ehashfn) -+{ -+ struct sock *sk, *reuse_sk; -+ bool prefetched; -+ -+ sk = skb_steal_sock(skb, refcounted, &prefetched); -+ if (!sk) -+ return NULL; -+ -+ if (!prefetched) -+ return sk; -+ -+ if (sk->sk_protocol == IPPROTO_TCP) { -+ if (sk->sk_state != TCP_LISTEN) -+ return sk; -+ } else if (sk->sk_protocol == IPPROTO_UDP) { -+ if (sk->sk_state != TCP_CLOSE) -+ return sk; -+ } else { -+ return sk; -+ } -+ -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, ntohs(dport), -+ ehashfn); -+ if (!reuse_sk) -+ return sk; -+ -+ /* We've chosen a new reuseport sock which is never refcounted. This -+ * implies that sk also isn't refcounted. -+ */ -+ WARN_ON_ONCE(*refcounted); -+ -+ return reuse_sk; -+} -+ - static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, - struct sk_buff *skb, int doff, - const __be16 sport, -@@ -101,14 +141,20 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, - int iif, int sdif, - bool *refcounted) - { -- struct sock *sk = skb_steal_sock(skb, refcounted); -- -+ struct net *net = dev_net(skb_dst(skb)->dev); -+ const struct ipv6hdr *ip6h = ipv6_hdr(skb); -+ struct sock *sk; -+ -+ sk = inet6_steal_sock(net, skb, doff, &ip6h->saddr, sport, &ip6h->daddr, dport, -+ refcounted, inet6_ehashfn); -+ if (IS_ERR(sk)) -+ return NULL; - if (sk) - return sk; - -- return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, -- doff, &ipv6_hdr(skb)->saddr, sport, -- &ipv6_hdr(skb)->daddr, ntohs(dport), -+ return __inet6_lookup(net, hashinfo, skb, -+ doff, &ip6h->saddr, sport, -+ &ip6h->daddr, ntohs(dport), - iif, sdif, refcounted); - } - -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index ddfa2e67fdb51..a1b8eb147ce73 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -442,6 +442,46 @@ static inline struct sock *inet_lookup(struct net *net, - return sk; - } - -+static inline -+struct sock *inet_steal_sock(struct net *net, struct sk_buff *skb, int doff, -+ const __be32 saddr, const __be16 sport, -+ const __be32 daddr, const __be16 dport, -+ bool *refcounted, inet_ehashfn_t *ehashfn) -+{ -+ struct sock *sk, *reuse_sk; -+ bool prefetched; -+ -+ sk = skb_steal_sock(skb, refcounted, &prefetched); -+ if (!sk) -+ return NULL; -+ -+ if (!prefetched) -+ return sk; -+ -+ if (sk->sk_protocol == IPPROTO_TCP) { -+ if (sk->sk_state != TCP_LISTEN) -+ return sk; -+ } else if (sk->sk_protocol == IPPROTO_UDP) { -+ if (sk->sk_state != TCP_CLOSE) -+ return sk; -+ } else { -+ return sk; -+ } -+ -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, ntohs(dport), -+ ehashfn); -+ if (!reuse_sk) -+ return sk; -+ -+ /* We've chosen a new reuseport sock which is never refcounted. This -+ * implies that sk also isn't refcounted. -+ */ -+ WARN_ON_ONCE(*refcounted); -+ -+ return reuse_sk; -+} -+ - static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - struct sk_buff *skb, - int doff, -@@ -450,13 +490,18 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - const int sdif, - bool *refcounted) - { -- struct sock *sk = skb_steal_sock(skb, refcounted); -+ struct net *net = dev_net(skb_dst(skb)->dev); - const struct iphdr *iph = ip_hdr(skb); -+ struct sock *sk; - -+ sk = inet_steal_sock(net, skb, doff, iph->saddr, sport, iph->daddr, dport, -+ refcounted, inet_ehashfn); -+ if (IS_ERR(sk)) -+ return NULL; - if (sk) - return sk; - -- return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, -+ return __inet_lookup(net, hashinfo, skb, - doff, iph->saddr, sport, - iph->daddr, dport, inet_iif(skb), sdif, - refcounted); -diff --git a/include/net/sock.h b/include/net/sock.h -index d1f936ed97556..3a8b2cc23b914 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -2852,20 +2852,23 @@ sk_is_refcounted(struct sock *sk) - * skb_steal_sock - steal a socket from an sk_buff - * @skb: sk_buff to steal the socket from - * @refcounted: is set to true if the socket is reference-counted -+ * @prefetched: is set to true if the socket was assigned from bpf - */ - static inline struct sock * --skb_steal_sock(struct sk_buff *skb, bool *refcounted) -+skb_steal_sock(struct sk_buff *skb, bool *refcounted, bool *prefetched) - { - if (skb->sk) { - struct sock *sk = skb->sk; - - *refcounted = true; -- if (skb_sk_is_prefetched(skb)) -+ *prefetched = skb_sk_is_prefetched(skb); -+ if (*prefetched) - *refcounted = sk_is_refcounted(sk); - skb->destructor = NULL; - skb->sk = NULL; - return sk; - } -+ *prefetched = false; - *refcounted = false; - return NULL; - } -diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h -index 51b9aa640ad2a..1304bec5c97a0 100644 ---- a/include/uapi/linux/bpf.h -+++ b/include/uapi/linux/bpf.h -@@ -4079,9 +4079,6 @@ union bpf_attr { - * **-EOPNOTSUPP** if the operation is not supported, for example - * a call from outside of TC ingress. - * -- * **-ESOCKTNOSUPPORT** if the socket type is not supported -- * (reuseport). -- * - * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags) - * Description - * Helper is overloaded depending on BPF program type. This -diff --git a/net/core/filter.c b/net/core/filter.c -index 9fd7c88b5db4e..ccc97d54d9a8b 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -7257,8 +7257,6 @@ BPF_CALL_3(bpf_sk_assign, struct sk_buff *, skb, struct sock *, sk, u64, flags) - return -EOPNOTSUPP; - if (unlikely(dev_net(skb->dev) != sock_net(sk))) - return -ENETUNREACH; -- if (unlikely(sk_fullsock(sk) && sk->sk_reuseport)) -- return -ESOCKTNOSUPPORT; - if (sk_unhashed(sk)) - return -EOPNOTSUPP; - if (sk_is_refcounted(sk) && -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index 87686c9e4efca..58c2f8df5fd70 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -2442,7 +2442,11 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - if (udp4_csum_init(skb, uh, proto)) - goto csum_error; - -- sk = skb_steal_sock(skb, &refcounted); -+ sk = inet_steal_sock(net, skb, sizeof(struct udphdr), saddr, uh->source, daddr, uh->dest, -+ &refcounted, udp_ehashfn); -+ if (IS_ERR(sk)) -+ goto no_sk; -+ - if (sk) { - struct dst_entry *dst = skb_dst(skb); - int ret; -@@ -2463,7 +2467,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable); - if (sk) - return udp_unicast_rcv_skb(sk, skb, uh); -- -+no_sk: - if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) - goto drop; - nf_reset_ct(skb); -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index 3408376b1863b..91b757066c935 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -983,7 +983,11 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - goto csum_error; - - /* Check if the socket is already available, e.g. due to early demux */ -- sk = skb_steal_sock(skb, &refcounted); -+ sk = inet6_steal_sock(net, skb, sizeof(struct udphdr), saddr, uh->source, daddr, uh->dest, -+ &refcounted, udp6_ehashfn); -+ if (IS_ERR(sk)) -+ goto no_sk; -+ - if (sk) { - struct dst_entry *dst = skb_dst(skb); - int ret; -@@ -1017,7 +1021,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - goto report_csum_error; - return udp6_unicast_rcv_skb(sk, skb, uh); - } -- -+no_sk: - reason = SKB_DROP_REASON_NO_SOCKET; - - if (!uh->check) -diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h -index 51b9aa640ad2a..1304bec5c97a0 100644 ---- a/tools/include/uapi/linux/bpf.h -+++ b/tools/include/uapi/linux/bpf.h -@@ -4079,9 +4079,6 @@ union bpf_attr { - * **-EOPNOTSUPP** if the operation is not supported, for example - * a call from outside of TC ingress. - * -- * **-ESOCKTNOSUPPORT** if the socket type is not supported -- * (reuseport). -- * - * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags) - * Description - * Helper is overloaded depending on BPF program type. This --- -2.40.1 - diff --git a/queue-6.1/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch b/queue-6.1/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch deleted file mode 100644 index afeddbca1f7..00000000000 --- a/queue-6.1/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 54234a8d6225eeb23998faa12da812998995c956 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:07 +0200 -Subject: net: export inet_lookup_reuseport and inet6_lookup_reuseport - -From: Lorenz Bauer - -[ Upstream commit ce796e60b3b196b61fcc565df195443cbb846ef0 ] - -Rename the existing reuseport helpers for IPv4 and IPv6 so that they -can be invoked in the follow up commit. Export them so that building -DCCP and IPv6 as a module works. - -No change in functionality. - -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-3-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Stable-dep-of: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 7 +++++++ - include/net/inet_hashtables.h | 5 +++++ - net/ipv4/inet_hashtables.c | 15 ++++++++------- - net/ipv6/inet6_hashtables.c | 19 ++++++++++--------- - 4 files changed, 30 insertions(+), 16 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 56f1286583d3c..032ddab48f8f8 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -48,6 +48,13 @@ struct sock *__inet6_lookup_established(struct net *net, - const u16 hnum, const int dif, - const int sdif); - -+struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, -+ __be16 sport, -+ const struct in6_addr *daddr, -+ unsigned short hnum); -+ - struct sock *inet6_lookup_listener(struct net *net, - struct inet_hashinfo *hashinfo, - struct sk_buff *skb, int doff, -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index 99bd823e97f62..8734f3488f5d0 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -379,6 +379,11 @@ struct sock *__inet_lookup_established(struct net *net, - const __be32 daddr, const u16 hnum, - const int dif, const int sdif); - -+struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ __be32 saddr, __be16 sport, -+ __be32 daddr, unsigned short hnum); -+ - static inline struct sock * - inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, - const __be32 saddr, const __be16 sport, -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index c19b462662ad0..6ed92624c95c4 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -332,10 +332,10 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - --static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, int doff, -- __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) -+struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ __be32 saddr, __be16 sport, -+ __be32 daddr, unsigned short hnum) - { - struct sock *reuse_sk = NULL; - u32 phash; -@@ -346,6 +346,7 @@ static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, - } - return reuse_sk; - } -+EXPORT_SYMBOL_GPL(inet_lookup_reuseport); - - /* - * Here are some nice properties to exploit here. The BSD API -@@ -369,8 +370,8 @@ static struct sock *inet_lhash2_lookup(struct net *net, - sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) { - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { -- result = lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ result = inet_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum); - if (result) - return result; - -@@ -399,7 +400,7 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c -index b64b49012655e..b7c56867314ed 100644 ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -111,12 +111,12 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - --static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, int doff, -- const struct in6_addr *saddr, -- __be16 sport, -- const struct in6_addr *daddr, -- unsigned short hnum) -+struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, -+ __be16 sport, -+ const struct in6_addr *daddr, -+ unsigned short hnum) - { - struct sock *reuse_sk = NULL; - u32 phash; -@@ -127,6 +127,7 @@ static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, - } - return reuse_sk; - } -+EXPORT_SYMBOL_GPL(inet6_lookup_reuseport); - - /* called with rcu_read_lock() */ - static struct sock *inet6_lhash2_lookup(struct net *net, -@@ -143,8 +144,8 @@ static struct sock *inet6_lhash2_lookup(struct net *net, - sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) { - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { -- result = lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ result = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum); - if (result) - return result; - -@@ -175,7 +176,7 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); - if (reuse_sk) - sk = reuse_sk; - return sk; --- -2.40.1 - diff --git a/queue-6.1/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch b/queue-6.1/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch deleted file mode 100644 index fd20519497e..00000000000 --- a/queue-6.1/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch +++ /dev/null @@ -1,63 +0,0 @@ -From cb889400f6dac86d95708d710ed5885dc9b8d78f Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 15 Aug 2023 09:53:41 +0100 -Subject: net: Fix slab-out-of-bounds in inet[6]_steal_sock - -From: Lorenz Bauer - -[ Upstream commit 8897562f67b3e61ad736cd5c9f307447d33280e4 ] - -Kumar reported a KASAN splat in tcp_v6_rcv: - - bash-5.2# ./test_progs -t btf_skc_cls_ingress - ... - [ 51.810085] BUG: KASAN: slab-out-of-bounds in tcp_v6_rcv+0x2d7d/0x3440 - [ 51.810458] Read of size 2 at addr ffff8881053f038c by task test_progs/226 - -The problem is that inet[6]_steal_sock accesses sk->sk_protocol without -accounting for request or timewait sockets. To fix this we can't just -check sock_common->skc_reuseport since that flag is present on timewait -sockets. - -Instead, add a fullsock check to avoid the out of bands access of sk_protocol. - -Fixes: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Reported-by: Kumar Kartikeya Dwivedi -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230815-bpf-next-v2-1-95126eaa4c1b@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 2 +- - include/net/inet_hashtables.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 475e672b4facc..12780b8fb5630 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -107,7 +107,7 @@ struct sock *inet6_steal_sock(struct net *net, struct sk_buff *skb, int doff, - if (!sk) - return NULL; - -- if (!prefetched) -+ if (!prefetched || !sk_fullsock(sk)) - return sk; - - if (sk->sk_protocol == IPPROTO_TCP) { -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index a1b8eb147ce73..9414cb4e6e624 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -455,7 +455,7 @@ struct sock *inet_steal_sock(struct net *net, struct sk_buff *skb, int doff, - if (!sk) - return NULL; - -- if (!prefetched) -+ if (!prefetched || !sk_fullsock(sk)) - return sk; - - if (sk->sk_protocol == IPPROTO_TCP) { --- -2.40.1 - diff --git a/queue-6.1/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch b/queue-6.1/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch deleted file mode 100644 index e9b0430a816..00000000000 --- a/queue-6.1/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 74bdfab4fd7c641e55f7fe9d1be9687eeb01df67 Mon Sep 17 00:00:00 2001 -From: Lorenz Bauer -Date: Mon, 31 Jul 2023 11:42:53 +0200 -Subject: net: remove duplicate INDIRECT_CALLABLE_DECLARE of udp[6]_ehashfn - -From: Lorenz Bauer - -commit 74bdfab4fd7c641e55f7fe9d1be9687eeb01df67 upstream. - -There are already INDIRECT_CALLABLE_DECLARE in the hashtable -headers, no need to declare them again. - -Fixes: 0f495f761722 ("net: remove duplicate reuseport_lookup functions") -Suggested-by: Martin Lau -Signed-off-by: Lorenz Bauer -Reviewed-by: Kuniyuki Iwashima -Link: https://lore.kernel.org/r/20230731-indir-call-v1-1-4cd0aeaee64f@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Greg Kroah-Hartman ---- - net/ipv4/inet_hashtables.c | 2 -- - net/ipv6/inet6_hashtables.c | 2 -- - 2 files changed, 4 deletions(-) - ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -333,8 +333,6 @@ static inline int compute_score(struct s - return score; - } - --INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -- - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -112,8 +112,6 @@ static inline int compute_score(struct s - return score; - } - --INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -- - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, diff --git a/queue-6.1/net-remove-duplicate-reuseport_lookup-functions.patch b/queue-6.1/net-remove-duplicate-reuseport_lookup-functions.patch deleted file mode 100644 index 66332944191..00000000000 --- a/queue-6.1/net-remove-duplicate-reuseport_lookup-functions.patch +++ /dev/null @@ -1,365 +0,0 @@ -From 3cf7940a98d9e474fc7a560b2484a54d5c728b17 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:08 +0200 -Subject: net: remove duplicate reuseport_lookup functions - -From: Lorenz Bauer - -[ Upstream commit 0f495f7617229772403e683033abc473f0f0553c ] - -There are currently four copies of reuseport_lookup: one each for -(TCP, UDP)x(IPv4, IPv6). This forces us to duplicate all callers of -those functions as well. This is already the case for sk_lookup -helpers (inet,inet6,udp4,udp6)_lookup_run_bpf. - -There are two differences between the reuseport_lookup helpers: - -1. They call different hash functions depending on protocol -2. UDP reuseport_lookup checks that sk_state != TCP_ESTABLISHED - -Move the check for sk_state into the caller and use the INDIRECT_CALL -infrastructure to cut down the helpers to one per IP version. - -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-4-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Stable-dep-of: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 11 ++++++++- - include/net/inet_hashtables.h | 15 ++++++++----- - net/ipv4/inet_hashtables.c | 20 +++++++++++------ - net/ipv4/udp.c | 34 +++++++++++----------------- - net/ipv6/inet6_hashtables.c | 14 ++++++++---- - net/ipv6/udp.c | 41 +++++++++++++--------------------- - 6 files changed, 72 insertions(+), 63 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 032ddab48f8f8..f89320b6fee31 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -48,12 +48,21 @@ struct sock *__inet6_lookup_established(struct net *net, - const u16 hnum, const int dif, - const int sdif); - -+typedef u32 (inet6_ehashfn_t)(const struct net *net, -+ const struct in6_addr *laddr, const u16 lport, -+ const struct in6_addr *faddr, const __be16 fport); -+ -+inet6_ehashfn_t inet6_ehashfn; -+ -+INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -+ - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, - __be16 sport, - const struct in6_addr *daddr, -- unsigned short hnum); -+ unsigned short hnum, -+ inet6_ehashfn_t *ehashfn); - - struct sock *inet6_lookup_listener(struct net *net, - struct inet_hashinfo *hashinfo, -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index 8734f3488f5d0..ddfa2e67fdb51 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -379,10 +379,19 @@ struct sock *__inet_lookup_established(struct net *net, - const __be32 daddr, const u16 hnum, - const int dif, const int sdif); - -+typedef u32 (inet_ehashfn_t)(const struct net *net, -+ const __be32 laddr, const __u16 lport, -+ const __be32 faddr, const __be16 fport); -+ -+inet_ehashfn_t inet_ehashfn; -+ -+INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -+ - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum); -+ __be32 daddr, unsigned short hnum, -+ inet_ehashfn_t *ehashfn); - - static inline struct sock * - inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, -@@ -453,10 +462,6 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - refcounted); - } - --u32 inet6_ehashfn(const struct net *net, -- const struct in6_addr *laddr, const u16 lport, -- const struct in6_addr *faddr, const __be16 fport); -- - static inline void sk_daddr_set(struct sock *sk, __be32 addr) - { - sk->sk_daddr = addr; /* alias of inet_daddr */ -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index 6ed92624c95c4..970da5b2bfe9c 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -28,9 +28,9 @@ - #include - #include - --static u32 inet_ehashfn(const struct net *net, const __be32 laddr, -- const __u16 lport, const __be32 faddr, -- const __be16 fport) -+u32 inet_ehashfn(const struct net *net, const __be32 laddr, -+ const __u16 lport, const __be32 faddr, -+ const __be16 fport) - { - static u32 inet_ehash_secret __read_mostly; - -@@ -39,6 +39,7 @@ static u32 inet_ehashfn(const struct net *net, const __be32 laddr, - return __inet_ehashfn(laddr, lport, faddr, fport, - inet_ehash_secret + net_hash_mix(net)); - } -+EXPORT_SYMBOL_GPL(inet_ehashfn); - - /* This function handles inet_sock, but also timewait and request sockets - * for IPv4/IPv6. -@@ -332,16 +333,20 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - -+INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -+ - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) -+ __be32 daddr, unsigned short hnum, -+ inet_ehashfn_t *ehashfn) - { - struct sock *reuse_sk = NULL; - u32 phash; - - if (sk->sk_reuseport) { -- phash = inet_ehashfn(net, daddr, hnum, saddr, sport); -+ phash = INDIRECT_CALL_2(ehashfn, udp_ehashfn, inet_ehashfn, -+ net, daddr, hnum, saddr, sport); - reuse_sk = reuseport_select_sock(sk, phash, skb, doff); - } - return reuse_sk; -@@ -371,7 +376,7 @@ static struct sock *inet_lhash2_lookup(struct net *net, - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { - result = inet_lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ saddr, sport, daddr, hnum, inet_ehashfn); - if (result) - return result; - -@@ -400,7 +405,8 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum, -+ inet_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index 42c1f7d9a980a..87686c9e4efca 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -400,9 +400,9 @@ static int compute_score(struct sock *sk, struct net *net, - return score; - } - --static u32 udp_ehashfn(const struct net *net, const __be32 laddr, -- const __u16 lport, const __be32 faddr, -- const __be16 fport) -+INDIRECT_CALLABLE_SCOPE -+u32 udp_ehashfn(const struct net *net, const __be32 laddr, const __u16 lport, -+ const __be32 faddr, const __be16 fport) - { - static u32 udp_ehash_secret __read_mostly; - -@@ -412,22 +412,6 @@ static u32 udp_ehashfn(const struct net *net, const __be32 laddr, - udp_ehash_secret + net_hash_mix(net)); - } - --static struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, -- __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) --{ -- struct sock *reuse_sk = NULL; -- u32 hash; -- -- if (sk->sk_reuseport && sk->sk_state != TCP_ESTABLISHED) { -- hash = udp_ehashfn(net, daddr, hnum, saddr, sport); -- reuse_sk = reuseport_select_sock(sk, hash, skb, -- sizeof(struct udphdr)); -- } -- return reuse_sk; --} -- - /* called with rcu_read_lock() */ - static struct sock *udp4_lib_lookup2(struct net *net, - __be32 saddr, __be16 sport, -@@ -446,7 +430,14 @@ static struct sock *udp4_lib_lookup2(struct net *net, - daddr, hnum, dif, sdif); - if (score > badness) { - badness = score; -- result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ -+ if (sk->sk_state == TCP_ESTABLISHED) { -+ result = sk; -+ continue; -+ } -+ -+ result = inet_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp_ehashfn); - if (!result) { - result = sk; - continue; -@@ -485,7 +476,8 @@ static struct sock *udp4_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c -index b7c56867314ed..3616225c89ef6 100644 ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -39,6 +39,7 @@ u32 inet6_ehashfn(const struct net *net, - return __inet6_ehashfn(lhash, lport, fhash, fport, - inet6_ehash_secret + net_hash_mix(net)); - } -+EXPORT_SYMBOL_GPL(inet6_ehashfn); - - /* - * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so -@@ -111,18 +112,22 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - -+INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -+ - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, - __be16 sport, - const struct in6_addr *daddr, -- unsigned short hnum) -+ unsigned short hnum, -+ inet6_ehashfn_t *ehashfn) - { - struct sock *reuse_sk = NULL; - u32 phash; - - if (sk->sk_reuseport) { -- phash = inet6_ehashfn(net, daddr, hnum, saddr, sport); -+ phash = INDIRECT_CALL_INET(ehashfn, udp6_ehashfn, inet6_ehashfn, -+ net, daddr, hnum, saddr, sport); - reuse_sk = reuseport_select_sock(sk, phash, skb, doff); - } - return reuse_sk; -@@ -145,7 +150,7 @@ static struct sock *inet6_lhash2_lookup(struct net *net, - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { - result = inet6_lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ saddr, sport, daddr, hnum, inet6_ehashfn); - if (result) - return result; - -@@ -176,7 +181,8 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum, inet6_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index 64b36c2ba774a..3408376b1863b 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -70,11 +70,12 @@ int udpv6_init_sock(struct sock *sk) - return 0; - } - --static u32 udp6_ehashfn(const struct net *net, -- const struct in6_addr *laddr, -- const u16 lport, -- const struct in6_addr *faddr, -- const __be16 fport) -+INDIRECT_CALLABLE_SCOPE -+u32 udp6_ehashfn(const struct net *net, -+ const struct in6_addr *laddr, -+ const u16 lport, -+ const struct in6_addr *faddr, -+ const __be16 fport) - { - static u32 udp6_ehash_secret __read_mostly; - static u32 udp_ipv6_hash_secret __read_mostly; -@@ -159,24 +160,6 @@ static int compute_score(struct sock *sk, struct net *net, - return score; - } - --static struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, -- const struct in6_addr *saddr, -- __be16 sport, -- const struct in6_addr *daddr, -- unsigned int hnum) --{ -- struct sock *reuse_sk = NULL; -- u32 hash; -- -- if (sk->sk_reuseport && sk->sk_state != TCP_ESTABLISHED) { -- hash = udp6_ehashfn(net, daddr, hnum, saddr, sport); -- reuse_sk = reuseport_select_sock(sk, hash, skb, -- sizeof(struct udphdr)); -- } -- return reuse_sk; --} -- - /* called with rcu_read_lock() */ - static struct sock *udp6_lib_lookup2(struct net *net, - const struct in6_addr *saddr, __be16 sport, -@@ -194,7 +177,14 @@ static struct sock *udp6_lib_lookup2(struct net *net, - daddr, hnum, dif, sdif); - if (score > badness) { - badness = score; -- result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ -+ if (sk->sk_state == TCP_ESTABLISHED) { -+ result = sk; -+ continue; -+ } -+ -+ result = inet6_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp6_ehashfn); - if (!result) { - result = sk; - continue; -@@ -234,7 +224,8 @@ static inline struct sock *udp6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp6_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; --- -2.40.1 - diff --git a/queue-6.1/series b/queue-6.1/series index ecaec11fa31..90193a505f9 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -150,9 +150,6 @@ wifi-rtw89-debug-fix-error-handling-in-rtw89_debug_p.patch wifi-mt76-mt7921-fix-non-psc-channel-scan-fail.patch udp-re-score-reuseport-groups-when-connected-sockets.patch bpf-reject-unhashed-sockets-in-bpf_sk_assign.patch -net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch -net-remove-duplicate-reuseport_lookup-functions.patch -bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch wifi-mt76-testmode-add-nla_policy-for-mt76_tm_attr_t.patch spi-tegra20-sflash-fix-to-check-return-value-of-plat.patch can-gs_usb-gs_usb_receive_bulk_callback-count-rx-ove.patch @@ -173,7 +170,6 @@ bluetooth-hci_sync-avoid-use-after-free-in-dbg-for-h.patch net-tcp-fix-unexcepted-socket-die-when-snd_wnd-is-0.patch selftests-bpf-fix-repeat-option-when-kfunc_call-veri.patch selftests-bpf-clean-up-fmod_ret-in-bench_rename-test.patch -net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch net-memcg-fix-scope-of-sockmem-pressure-indicators.patch ice-ice_aq_check_events-fix-off-by-one-check-when-fi.patch crypto-caam-fix-unchecked-return-value-error.patch @@ -586,7 +582,6 @@ x86-sgx-break-up-long-non-preemptible-delays-in-sgx_vepc_release.patch perf-x86-uncore-correct-the-number-of-chas-on-emr.patch serial-sc16is7xx-remove-obsolete-out_thread-label.patch serial-sc16is7xx-fix-regression-with-gpio-configurat.patch -net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch tracing-zero-the-pipe-cpumask-on-alloc-to-avoid-spurious-ebusy.patch revert-drm-amd-display-do-not-set-drr-on-pipe-commit.patch md-free-resources-in-__md_stop.patch diff --git a/queue-6.4/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch b/queue-6.4/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch deleted file mode 100644 index a1813a7eaf5..00000000000 --- a/queue-6.4/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch +++ /dev/null @@ -1,332 +0,0 @@ -From 1c53f65cde5209d48cab6bec7b2592fa2b7e7f0f Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:11 +0200 -Subject: bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign - -From: Lorenz Bauer - -[ Upstream commit 9c02bec95954252c3c01bfbb3f7560e0b95ca955 ] - -Currently the bpf_sk_assign helper in tc BPF context refuses SO_REUSEPORT -sockets. This means we can't use the helper to steer traffic to Envoy, -which configures SO_REUSEPORT on its sockets. In turn, we're blocked -from removing TPROXY from our setup. - -The reason that bpf_sk_assign refuses such sockets is that the -bpf_sk_lookup helpers don't execute SK_REUSEPORT programs. Instead, -one of the reuseport sockets is selected by hash. This could cause -dispatch to the "wrong" socket: - - sk = bpf_sk_lookup_tcp(...) // select SO_REUSEPORT by hash - bpf_sk_assign(skb, sk) // SK_REUSEPORT wasn't executed - -Fixing this isn't as simple as invoking SK_REUSEPORT from the lookup -helpers unfortunately. In the tc context, L2 headers are at the start -of the skb, while SK_REUSEPORT expects L3 headers instead. - -Instead, we execute the SK_REUSEPORT program when the assigned socket -is pulled out of the skb, further up the stack. This creates some -trickiness with regards to refcounting as bpf_sk_assign will put both -refcounted and RCU freed sockets in skb->sk. reuseport sockets are RCU -freed. We can infer that the sk_assigned socket is RCU freed if the -reuseport lookup succeeds, but convincing yourself of this fact isn't -straight forward. Therefore we defensively check refcounting on the -sk_assign sock even though it's probably not required in practice. - -Fixes: 8e368dc72e86 ("bpf: Fix use of sk->sk_reuseport from sk_assign") -Fixes: cf7fbe660f2d ("bpf: Add socket assign support") -Co-developed-by: Daniel Borkmann -Signed-off-by: Daniel Borkmann -Cc: Joe Stringer -Link: https://lore.kernel.org/bpf/CACAyw98+qycmpQzKupquhkxbvWK4OFyDuuLMBNROnfWMZxUWeA@mail.gmail.com/ -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-7-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 56 +++++++++++++++++++++++++++++++--- - include/net/inet_hashtables.h | 49 +++++++++++++++++++++++++++-- - include/net/sock.h | 7 +++-- - include/uapi/linux/bpf.h | 3 -- - net/core/filter.c | 2 -- - net/ipv4/udp.c | 8 +++-- - net/ipv6/udp.c | 8 +++-- - tools/include/uapi/linux/bpf.h | 3 -- - 8 files changed, 115 insertions(+), 21 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index f89320b6fee31..475e672b4facc 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -94,6 +94,46 @@ static inline struct sock *__inet6_lookup(struct net *net, - daddr, hnum, dif, sdif); - } - -+static inline -+struct sock *inet6_steal_sock(struct net *net, struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, const __be16 sport, -+ const struct in6_addr *daddr, const __be16 dport, -+ bool *refcounted, inet6_ehashfn_t *ehashfn) -+{ -+ struct sock *sk, *reuse_sk; -+ bool prefetched; -+ -+ sk = skb_steal_sock(skb, refcounted, &prefetched); -+ if (!sk) -+ return NULL; -+ -+ if (!prefetched) -+ return sk; -+ -+ if (sk->sk_protocol == IPPROTO_TCP) { -+ if (sk->sk_state != TCP_LISTEN) -+ return sk; -+ } else if (sk->sk_protocol == IPPROTO_UDP) { -+ if (sk->sk_state != TCP_CLOSE) -+ return sk; -+ } else { -+ return sk; -+ } -+ -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, ntohs(dport), -+ ehashfn); -+ if (!reuse_sk) -+ return sk; -+ -+ /* We've chosen a new reuseport sock which is never refcounted. This -+ * implies that sk also isn't refcounted. -+ */ -+ WARN_ON_ONCE(*refcounted); -+ -+ return reuse_sk; -+} -+ - static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, - struct sk_buff *skb, int doff, - const __be16 sport, -@@ -101,14 +141,20 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, - int iif, int sdif, - bool *refcounted) - { -- struct sock *sk = skb_steal_sock(skb, refcounted); -- -+ struct net *net = dev_net(skb_dst(skb)->dev); -+ const struct ipv6hdr *ip6h = ipv6_hdr(skb); -+ struct sock *sk; -+ -+ sk = inet6_steal_sock(net, skb, doff, &ip6h->saddr, sport, &ip6h->daddr, dport, -+ refcounted, inet6_ehashfn); -+ if (IS_ERR(sk)) -+ return NULL; - if (sk) - return sk; - -- return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, -- doff, &ipv6_hdr(skb)->saddr, sport, -- &ipv6_hdr(skb)->daddr, ntohs(dport), -+ return __inet6_lookup(net, hashinfo, skb, -+ doff, &ip6h->saddr, sport, -+ &ip6h->daddr, ntohs(dport), - iif, sdif, refcounted); - } - -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index ddfa2e67fdb51..a1b8eb147ce73 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -442,6 +442,46 @@ static inline struct sock *inet_lookup(struct net *net, - return sk; - } - -+static inline -+struct sock *inet_steal_sock(struct net *net, struct sk_buff *skb, int doff, -+ const __be32 saddr, const __be16 sport, -+ const __be32 daddr, const __be16 dport, -+ bool *refcounted, inet_ehashfn_t *ehashfn) -+{ -+ struct sock *sk, *reuse_sk; -+ bool prefetched; -+ -+ sk = skb_steal_sock(skb, refcounted, &prefetched); -+ if (!sk) -+ return NULL; -+ -+ if (!prefetched) -+ return sk; -+ -+ if (sk->sk_protocol == IPPROTO_TCP) { -+ if (sk->sk_state != TCP_LISTEN) -+ return sk; -+ } else if (sk->sk_protocol == IPPROTO_UDP) { -+ if (sk->sk_state != TCP_CLOSE) -+ return sk; -+ } else { -+ return sk; -+ } -+ -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, ntohs(dport), -+ ehashfn); -+ if (!reuse_sk) -+ return sk; -+ -+ /* We've chosen a new reuseport sock which is never refcounted. This -+ * implies that sk also isn't refcounted. -+ */ -+ WARN_ON_ONCE(*refcounted); -+ -+ return reuse_sk; -+} -+ - static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - struct sk_buff *skb, - int doff, -@@ -450,13 +490,18 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - const int sdif, - bool *refcounted) - { -- struct sock *sk = skb_steal_sock(skb, refcounted); -+ struct net *net = dev_net(skb_dst(skb)->dev); - const struct iphdr *iph = ip_hdr(skb); -+ struct sock *sk; - -+ sk = inet_steal_sock(net, skb, doff, iph->saddr, sport, iph->daddr, dport, -+ refcounted, inet_ehashfn); -+ if (IS_ERR(sk)) -+ return NULL; - if (sk) - return sk; - -- return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, -+ return __inet_lookup(net, hashinfo, skb, - doff, iph->saddr, sport, - iph->daddr, dport, inet_iif(skb), sdif, - refcounted); -diff --git a/include/net/sock.h b/include/net/sock.h -index d0d796d51a504..299c484bd4035 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -2826,20 +2826,23 @@ sk_is_refcounted(struct sock *sk) - * skb_steal_sock - steal a socket from an sk_buff - * @skb: sk_buff to steal the socket from - * @refcounted: is set to true if the socket is reference-counted -+ * @prefetched: is set to true if the socket was assigned from bpf - */ - static inline struct sock * --skb_steal_sock(struct sk_buff *skb, bool *refcounted) -+skb_steal_sock(struct sk_buff *skb, bool *refcounted, bool *prefetched) - { - if (skb->sk) { - struct sock *sk = skb->sk; - - *refcounted = true; -- if (skb_sk_is_prefetched(skb)) -+ *prefetched = skb_sk_is_prefetched(skb); -+ if (*prefetched) - *refcounted = sk_is_refcounted(sk); - skb->destructor = NULL; - skb->sk = NULL; - return sk; - } -+ *prefetched = false; - *refcounted = false; - return NULL; - } -diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h -index c994ff5b157cd..dc6db5c246dbe 100644 ---- a/include/uapi/linux/bpf.h -+++ b/include/uapi/linux/bpf.h -@@ -4145,9 +4145,6 @@ union bpf_attr { - * **-EOPNOTSUPP** if the operation is not supported, for example - * a call from outside of TC ingress. - * -- * **-ESOCKTNOSUPPORT** if the socket type is not supported -- * (reuseport). -- * - * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags) - * Description - * Helper is overloaded depending on BPF program type. This -diff --git a/net/core/filter.c b/net/core/filter.c -index a9e93d528869f..d5ca1f4c75b3e 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -7335,8 +7335,6 @@ BPF_CALL_3(bpf_sk_assign, struct sk_buff *, skb, struct sock *, sk, u64, flags) - return -EOPNOTSUPP; - if (unlikely(dev_net(skb->dev) != sock_net(sk))) - return -ENETUNREACH; -- if (unlikely(sk_fullsock(sk) && sk->sk_reuseport)) -- return -ESOCKTNOSUPPORT; - if (sk_unhashed(sk)) - return -EOPNOTSUPP; - if (sk_is_refcounted(sk) && -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index aaba742f6d103..dd4259d998fc9 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -2459,7 +2459,11 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - if (udp4_csum_init(skb, uh, proto)) - goto csum_error; - -- sk = skb_steal_sock(skb, &refcounted); -+ sk = inet_steal_sock(net, skb, sizeof(struct udphdr), saddr, uh->source, daddr, uh->dest, -+ &refcounted, udp_ehashfn); -+ if (IS_ERR(sk)) -+ goto no_sk; -+ - if (sk) { - struct dst_entry *dst = skb_dst(skb); - int ret; -@@ -2480,7 +2484,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable); - if (sk) - return udp_unicast_rcv_skb(sk, skb, uh); -- -+no_sk: - if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) - goto drop; - nf_reset_ct(skb); -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index 19f5a2fc8f378..3a36cc48353f2 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -992,7 +992,11 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - goto csum_error; - - /* Check if the socket is already available, e.g. due to early demux */ -- sk = skb_steal_sock(skb, &refcounted); -+ sk = inet6_steal_sock(net, skb, sizeof(struct udphdr), saddr, uh->source, daddr, uh->dest, -+ &refcounted, udp6_ehashfn); -+ if (IS_ERR(sk)) -+ goto no_sk; -+ - if (sk) { - struct dst_entry *dst = skb_dst(skb); - int ret; -@@ -1026,7 +1030,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - goto report_csum_error; - return udp6_unicast_rcv_skb(sk, skb, uh); - } -- -+no_sk: - reason = SKB_DROP_REASON_NO_SOCKET; - - if (!uh->check) -diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h -index c994ff5b157cd..dc6db5c246dbe 100644 ---- a/tools/include/uapi/linux/bpf.h -+++ b/tools/include/uapi/linux/bpf.h -@@ -4145,9 +4145,6 @@ union bpf_attr { - * **-EOPNOTSUPP** if the operation is not supported, for example - * a call from outside of TC ingress. - * -- * **-ESOCKTNOSUPPORT** if the socket type is not supported -- * (reuseport). -- * - * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags) - * Description - * Helper is overloaded depending on BPF program type. This --- -2.40.1 - diff --git a/queue-6.4/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch b/queue-6.4/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch deleted file mode 100644 index 9ef14749c7d..00000000000 --- a/queue-6.4/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 2e96dd1287139a03a298d686375ba0e638370ead Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:07 +0200 -Subject: net: export inet_lookup_reuseport and inet6_lookup_reuseport - -From: Lorenz Bauer - -[ Upstream commit ce796e60b3b196b61fcc565df195443cbb846ef0 ] - -Rename the existing reuseport helpers for IPv4 and IPv6 so that they -can be invoked in the follow up commit. Export them so that building -DCCP and IPv6 as a module works. - -No change in functionality. - -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-3-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Stable-dep-of: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 7 +++++++ - include/net/inet_hashtables.h | 5 +++++ - net/ipv4/inet_hashtables.c | 15 ++++++++------- - net/ipv6/inet6_hashtables.c | 19 ++++++++++--------- - 4 files changed, 30 insertions(+), 16 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 56f1286583d3c..032ddab48f8f8 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -48,6 +48,13 @@ struct sock *__inet6_lookup_established(struct net *net, - const u16 hnum, const int dif, - const int sdif); - -+struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, -+ __be16 sport, -+ const struct in6_addr *daddr, -+ unsigned short hnum); -+ - struct sock *inet6_lookup_listener(struct net *net, - struct inet_hashinfo *hashinfo, - struct sk_buff *skb, int doff, -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index 99bd823e97f62..8734f3488f5d0 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -379,6 +379,11 @@ struct sock *__inet_lookup_established(struct net *net, - const __be32 daddr, const u16 hnum, - const int dif, const int sdif); - -+struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ __be32 saddr, __be16 sport, -+ __be32 daddr, unsigned short hnum); -+ - static inline struct sock * - inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, - const __be32 saddr, const __be16 sport, -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index 0819d6001b9ab..ecb838460629e 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -332,10 +332,10 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - --static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, int doff, -- __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) -+struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ __be32 saddr, __be16 sport, -+ __be32 daddr, unsigned short hnum) - { - struct sock *reuse_sk = NULL; - u32 phash; -@@ -346,6 +346,7 @@ static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, - } - return reuse_sk; - } -+EXPORT_SYMBOL_GPL(inet_lookup_reuseport); - - /* - * Here are some nice properties to exploit here. The BSD API -@@ -369,8 +370,8 @@ static struct sock *inet_lhash2_lookup(struct net *net, - sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) { - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { -- result = lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ result = inet_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum); - if (result) - return result; - -@@ -399,7 +400,7 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c -index b64b49012655e..b7c56867314ed 100644 ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -111,12 +111,12 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - --static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, int doff, -- const struct in6_addr *saddr, -- __be16 sport, -- const struct in6_addr *daddr, -- unsigned short hnum) -+struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, -+ __be16 sport, -+ const struct in6_addr *daddr, -+ unsigned short hnum) - { - struct sock *reuse_sk = NULL; - u32 phash; -@@ -127,6 +127,7 @@ static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, - } - return reuse_sk; - } -+EXPORT_SYMBOL_GPL(inet6_lookup_reuseport); - - /* called with rcu_read_lock() */ - static struct sock *inet6_lhash2_lookup(struct net *net, -@@ -143,8 +144,8 @@ static struct sock *inet6_lhash2_lookup(struct net *net, - sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) { - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { -- result = lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ result = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum); - if (result) - return result; - -@@ -175,7 +176,7 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); - if (reuse_sk) - sk = reuse_sk; - return sk; --- -2.40.1 - diff --git a/queue-6.4/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch b/queue-6.4/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch deleted file mode 100644 index 65a3733c4f8..00000000000 --- a/queue-6.4/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 14a7c473d8d22952b08334d2657356e4926a8251 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 15 Aug 2023 09:53:41 +0100 -Subject: net: Fix slab-out-of-bounds in inet[6]_steal_sock - -From: Lorenz Bauer - -[ Upstream commit 8897562f67b3e61ad736cd5c9f307447d33280e4 ] - -Kumar reported a KASAN splat in tcp_v6_rcv: - - bash-5.2# ./test_progs -t btf_skc_cls_ingress - ... - [ 51.810085] BUG: KASAN: slab-out-of-bounds in tcp_v6_rcv+0x2d7d/0x3440 - [ 51.810458] Read of size 2 at addr ffff8881053f038c by task test_progs/226 - -The problem is that inet[6]_steal_sock accesses sk->sk_protocol without -accounting for request or timewait sockets. To fix this we can't just -check sock_common->skc_reuseport since that flag is present on timewait -sockets. - -Instead, add a fullsock check to avoid the out of bands access of sk_protocol. - -Fixes: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Reported-by: Kumar Kartikeya Dwivedi -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230815-bpf-next-v2-1-95126eaa4c1b@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 2 +- - include/net/inet_hashtables.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 475e672b4facc..12780b8fb5630 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -107,7 +107,7 @@ struct sock *inet6_steal_sock(struct net *net, struct sk_buff *skb, int doff, - if (!sk) - return NULL; - -- if (!prefetched) -+ if (!prefetched || !sk_fullsock(sk)) - return sk; - - if (sk->sk_protocol == IPPROTO_TCP) { -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index a1b8eb147ce73..9414cb4e6e624 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -455,7 +455,7 @@ struct sock *inet_steal_sock(struct net *net, struct sk_buff *skb, int doff, - if (!sk) - return NULL; - -- if (!prefetched) -+ if (!prefetched || !sk_fullsock(sk)) - return sk; - - if (sk->sk_protocol == IPPROTO_TCP) { --- -2.40.1 - diff --git a/queue-6.4/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch b/queue-6.4/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch deleted file mode 100644 index e9b0430a816..00000000000 --- a/queue-6.4/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 74bdfab4fd7c641e55f7fe9d1be9687eeb01df67 Mon Sep 17 00:00:00 2001 -From: Lorenz Bauer -Date: Mon, 31 Jul 2023 11:42:53 +0200 -Subject: net: remove duplicate INDIRECT_CALLABLE_DECLARE of udp[6]_ehashfn - -From: Lorenz Bauer - -commit 74bdfab4fd7c641e55f7fe9d1be9687eeb01df67 upstream. - -There are already INDIRECT_CALLABLE_DECLARE in the hashtable -headers, no need to declare them again. - -Fixes: 0f495f761722 ("net: remove duplicate reuseport_lookup functions") -Suggested-by: Martin Lau -Signed-off-by: Lorenz Bauer -Reviewed-by: Kuniyuki Iwashima -Link: https://lore.kernel.org/r/20230731-indir-call-v1-1-4cd0aeaee64f@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Greg Kroah-Hartman ---- - net/ipv4/inet_hashtables.c | 2 -- - net/ipv6/inet6_hashtables.c | 2 -- - 2 files changed, 4 deletions(-) - ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -333,8 +333,6 @@ static inline int compute_score(struct s - return score; - } - --INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -- - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -112,8 +112,6 @@ static inline int compute_score(struct s - return score; - } - --INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -- - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, diff --git a/queue-6.4/net-remove-duplicate-reuseport_lookup-functions.patch b/queue-6.4/net-remove-duplicate-reuseport_lookup-functions.patch deleted file mode 100644 index 95f61fb3001..00000000000 --- a/queue-6.4/net-remove-duplicate-reuseport_lookup-functions.patch +++ /dev/null @@ -1,365 +0,0 @@ -From 0b1126906102cec0e95f1c6e286c23db7d68ba76 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:08 +0200 -Subject: net: remove duplicate reuseport_lookup functions - -From: Lorenz Bauer - -[ Upstream commit 0f495f7617229772403e683033abc473f0f0553c ] - -There are currently four copies of reuseport_lookup: one each for -(TCP, UDP)x(IPv4, IPv6). This forces us to duplicate all callers of -those functions as well. This is already the case for sk_lookup -helpers (inet,inet6,udp4,udp6)_lookup_run_bpf. - -There are two differences between the reuseport_lookup helpers: - -1. They call different hash functions depending on protocol -2. UDP reuseport_lookup checks that sk_state != TCP_ESTABLISHED - -Move the check for sk_state into the caller and use the INDIRECT_CALL -infrastructure to cut down the helpers to one per IP version. - -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-4-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Stable-dep-of: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 11 ++++++++- - include/net/inet_hashtables.h | 15 ++++++++----- - net/ipv4/inet_hashtables.c | 20 +++++++++++------ - net/ipv4/udp.c | 34 +++++++++++----------------- - net/ipv6/inet6_hashtables.c | 14 ++++++++---- - net/ipv6/udp.c | 41 +++++++++++++--------------------- - 6 files changed, 72 insertions(+), 63 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 032ddab48f8f8..f89320b6fee31 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -48,12 +48,21 @@ struct sock *__inet6_lookup_established(struct net *net, - const u16 hnum, const int dif, - const int sdif); - -+typedef u32 (inet6_ehashfn_t)(const struct net *net, -+ const struct in6_addr *laddr, const u16 lport, -+ const struct in6_addr *faddr, const __be16 fport); -+ -+inet6_ehashfn_t inet6_ehashfn; -+ -+INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -+ - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, - __be16 sport, - const struct in6_addr *daddr, -- unsigned short hnum); -+ unsigned short hnum, -+ inet6_ehashfn_t *ehashfn); - - struct sock *inet6_lookup_listener(struct net *net, - struct inet_hashinfo *hashinfo, -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index 8734f3488f5d0..ddfa2e67fdb51 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -379,10 +379,19 @@ struct sock *__inet_lookup_established(struct net *net, - const __be32 daddr, const u16 hnum, - const int dif, const int sdif); - -+typedef u32 (inet_ehashfn_t)(const struct net *net, -+ const __be32 laddr, const __u16 lport, -+ const __be32 faddr, const __be16 fport); -+ -+inet_ehashfn_t inet_ehashfn; -+ -+INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -+ - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum); -+ __be32 daddr, unsigned short hnum, -+ inet_ehashfn_t *ehashfn); - - static inline struct sock * - inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, -@@ -453,10 +462,6 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - refcounted); - } - --u32 inet6_ehashfn(const struct net *net, -- const struct in6_addr *laddr, const u16 lport, -- const struct in6_addr *faddr, const __be16 fport); -- - static inline void sk_daddr_set(struct sock *sk, __be32 addr) - { - sk->sk_daddr = addr; /* alias of inet_daddr */ -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index ecb838460629e..0a7a726464d9d 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -28,9 +28,9 @@ - #include - #include - --static u32 inet_ehashfn(const struct net *net, const __be32 laddr, -- const __u16 lport, const __be32 faddr, -- const __be16 fport) -+u32 inet_ehashfn(const struct net *net, const __be32 laddr, -+ const __u16 lport, const __be32 faddr, -+ const __be16 fport) - { - static u32 inet_ehash_secret __read_mostly; - -@@ -39,6 +39,7 @@ static u32 inet_ehashfn(const struct net *net, const __be32 laddr, - return __inet_ehashfn(laddr, lport, faddr, fport, - inet_ehash_secret + net_hash_mix(net)); - } -+EXPORT_SYMBOL_GPL(inet_ehashfn); - - /* This function handles inet_sock, but also timewait and request sockets - * for IPv4/IPv6. -@@ -332,16 +333,20 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - -+INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -+ - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) -+ __be32 daddr, unsigned short hnum, -+ inet_ehashfn_t *ehashfn) - { - struct sock *reuse_sk = NULL; - u32 phash; - - if (sk->sk_reuseport) { -- phash = inet_ehashfn(net, daddr, hnum, saddr, sport); -+ phash = INDIRECT_CALL_2(ehashfn, udp_ehashfn, inet_ehashfn, -+ net, daddr, hnum, saddr, sport); - reuse_sk = reuseport_select_sock(sk, phash, skb, doff); - } - return reuse_sk; -@@ -371,7 +376,7 @@ static struct sock *inet_lhash2_lookup(struct net *net, - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { - result = inet_lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ saddr, sport, daddr, hnum, inet_ehashfn); - if (result) - return result; - -@@ -400,7 +405,8 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum, -+ inet_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index a3302136ce92e..aaba742f6d103 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -407,9 +407,9 @@ static int compute_score(struct sock *sk, struct net *net, - return score; - } - --static u32 udp_ehashfn(const struct net *net, const __be32 laddr, -- const __u16 lport, const __be32 faddr, -- const __be16 fport) -+INDIRECT_CALLABLE_SCOPE -+u32 udp_ehashfn(const struct net *net, const __be32 laddr, const __u16 lport, -+ const __be32 faddr, const __be16 fport) - { - static u32 udp_ehash_secret __read_mostly; - -@@ -419,22 +419,6 @@ static u32 udp_ehashfn(const struct net *net, const __be32 laddr, - udp_ehash_secret + net_hash_mix(net)); - } - --static struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, -- __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) --{ -- struct sock *reuse_sk = NULL; -- u32 hash; -- -- if (sk->sk_reuseport && sk->sk_state != TCP_ESTABLISHED) { -- hash = udp_ehashfn(net, daddr, hnum, saddr, sport); -- reuse_sk = reuseport_select_sock(sk, hash, skb, -- sizeof(struct udphdr)); -- } -- return reuse_sk; --} -- - /* called with rcu_read_lock() */ - static struct sock *udp4_lib_lookup2(struct net *net, - __be32 saddr, __be16 sport, -@@ -453,7 +437,14 @@ static struct sock *udp4_lib_lookup2(struct net *net, - daddr, hnum, dif, sdif); - if (score > badness) { - badness = score; -- result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ -+ if (sk->sk_state == TCP_ESTABLISHED) { -+ result = sk; -+ continue; -+ } -+ -+ result = inet_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp_ehashfn); - if (!result) { - result = sk; - continue; -@@ -492,7 +483,8 @@ static struct sock *udp4_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c -index b7c56867314ed..3616225c89ef6 100644 ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -39,6 +39,7 @@ u32 inet6_ehashfn(const struct net *net, - return __inet6_ehashfn(lhash, lport, fhash, fport, - inet6_ehash_secret + net_hash_mix(net)); - } -+EXPORT_SYMBOL_GPL(inet6_ehashfn); - - /* - * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so -@@ -111,18 +112,22 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - -+INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -+ - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, - __be16 sport, - const struct in6_addr *daddr, -- unsigned short hnum) -+ unsigned short hnum, -+ inet6_ehashfn_t *ehashfn) - { - struct sock *reuse_sk = NULL; - u32 phash; - - if (sk->sk_reuseport) { -- phash = inet6_ehashfn(net, daddr, hnum, saddr, sport); -+ phash = INDIRECT_CALL_INET(ehashfn, udp6_ehashfn, inet6_ehashfn, -+ net, daddr, hnum, saddr, sport); - reuse_sk = reuseport_select_sock(sk, phash, skb, doff); - } - return reuse_sk; -@@ -145,7 +150,7 @@ static struct sock *inet6_lhash2_lookup(struct net *net, - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { - result = inet6_lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ saddr, sport, daddr, hnum, inet6_ehashfn); - if (result) - return result; - -@@ -176,7 +181,8 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum, inet6_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index 9c7457823eb97..19f5a2fc8f378 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -72,11 +72,12 @@ int udpv6_init_sock(struct sock *sk) - return 0; - } - --static u32 udp6_ehashfn(const struct net *net, -- const struct in6_addr *laddr, -- const u16 lport, -- const struct in6_addr *faddr, -- const __be16 fport) -+INDIRECT_CALLABLE_SCOPE -+u32 udp6_ehashfn(const struct net *net, -+ const struct in6_addr *laddr, -+ const u16 lport, -+ const struct in6_addr *faddr, -+ const __be16 fport) - { - static u32 udp6_ehash_secret __read_mostly; - static u32 udp_ipv6_hash_secret __read_mostly; -@@ -161,24 +162,6 @@ static int compute_score(struct sock *sk, struct net *net, - return score; - } - --static struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, -- const struct in6_addr *saddr, -- __be16 sport, -- const struct in6_addr *daddr, -- unsigned int hnum) --{ -- struct sock *reuse_sk = NULL; -- u32 hash; -- -- if (sk->sk_reuseport && sk->sk_state != TCP_ESTABLISHED) { -- hash = udp6_ehashfn(net, daddr, hnum, saddr, sport); -- reuse_sk = reuseport_select_sock(sk, hash, skb, -- sizeof(struct udphdr)); -- } -- return reuse_sk; --} -- - /* called with rcu_read_lock() */ - static struct sock *udp6_lib_lookup2(struct net *net, - const struct in6_addr *saddr, __be16 sport, -@@ -196,7 +179,14 @@ static struct sock *udp6_lib_lookup2(struct net *net, - daddr, hnum, dif, sdif); - if (score > badness) { - badness = score; -- result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ -+ if (sk->sk_state == TCP_ESTABLISHED) { -+ result = sk; -+ continue; -+ } -+ -+ result = inet6_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp6_ehashfn); - if (!result) { - result = sk; - continue; -@@ -236,7 +226,8 @@ static inline struct sock *udp6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp6_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; --- -2.40.1 - diff --git a/queue-6.4/series b/queue-6.4/series index affad6d9ed7..37ed1b964a4 100644 --- a/queue-6.4/series +++ b/queue-6.4/series @@ -165,9 +165,6 @@ wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch wifi-mt76-mt7996-fix-wa-event-ring-size.patch udp-re-score-reuseport-groups-when-connected-sockets.patch bpf-reject-unhashed-sockets-in-bpf_sk_assign.patch -net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch -net-remove-duplicate-reuseport_lookup-functions.patch -bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch wifi-mt76-mt7915-fix-command-timeout-in-ap-stop-peri.patch wifi-mt76-mt7915-fix-capabilities-in-non-ap-mode.patch wifi-mt76-mt7915-remove-vht160-capability-on-mt7915.patch @@ -207,7 +204,6 @@ bluetooth-hci_event-drop-only-unbound-cis-if-set-cig.patch net-tcp-fix-unexcepted-socket-die-when-snd_wnd-is-0.patch selftests-bpf-fix-repeat-option-when-kfunc_call-veri.patch selftests-bpf-clean-up-fmod_ret-in-bench_rename-test.patch -net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch net-hns3-move-dump-regs-function-to-a-separate-file.patch net-hns3-support-tlv-in-regs-data-for-hns3-pf-driver.patch net-hns3-fix-wrong-rpu-tln-reg-issue.patch @@ -731,6 +727,5 @@ selftests-memfd-sysctl-fix-memfd_noexec_scope_noexec.patch memfd-do-not-eacces-old-memfd_create-users-with-vm.m.patch memfd-improve-userspace-warnings-for-missing-exec-re.patch revert-memfd-improve-userspace-warnings-for-missing-exec-related-flags.patch -net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch tracing-zero-the-pipe-cpumask-on-alloc-to-avoid-spurious-ebusy.patch revert-drm-amd-display-do-not-set-drr-on-pipe-commit.patch diff --git a/queue-6.5/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch b/queue-6.5/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch deleted file mode 100644 index ba8ee4848d3..00000000000 --- a/queue-6.5/bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch +++ /dev/null @@ -1,332 +0,0 @@ -From 2d2c2b92cee4baec44fee3a848187a7bc2c33192 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:11 +0200 -Subject: bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign - -From: Lorenz Bauer - -[ Upstream commit 9c02bec95954252c3c01bfbb3f7560e0b95ca955 ] - -Currently the bpf_sk_assign helper in tc BPF context refuses SO_REUSEPORT -sockets. This means we can't use the helper to steer traffic to Envoy, -which configures SO_REUSEPORT on its sockets. In turn, we're blocked -from removing TPROXY from our setup. - -The reason that bpf_sk_assign refuses such sockets is that the -bpf_sk_lookup helpers don't execute SK_REUSEPORT programs. Instead, -one of the reuseport sockets is selected by hash. This could cause -dispatch to the "wrong" socket: - - sk = bpf_sk_lookup_tcp(...) // select SO_REUSEPORT by hash - bpf_sk_assign(skb, sk) // SK_REUSEPORT wasn't executed - -Fixing this isn't as simple as invoking SK_REUSEPORT from the lookup -helpers unfortunately. In the tc context, L2 headers are at the start -of the skb, while SK_REUSEPORT expects L3 headers instead. - -Instead, we execute the SK_REUSEPORT program when the assigned socket -is pulled out of the skb, further up the stack. This creates some -trickiness with regards to refcounting as bpf_sk_assign will put both -refcounted and RCU freed sockets in skb->sk. reuseport sockets are RCU -freed. We can infer that the sk_assigned socket is RCU freed if the -reuseport lookup succeeds, but convincing yourself of this fact isn't -straight forward. Therefore we defensively check refcounting on the -sk_assign sock even though it's probably not required in practice. - -Fixes: 8e368dc72e86 ("bpf: Fix use of sk->sk_reuseport from sk_assign") -Fixes: cf7fbe660f2d ("bpf: Add socket assign support") -Co-developed-by: Daniel Borkmann -Signed-off-by: Daniel Borkmann -Cc: Joe Stringer -Link: https://lore.kernel.org/bpf/CACAyw98+qycmpQzKupquhkxbvWK4OFyDuuLMBNROnfWMZxUWeA@mail.gmail.com/ -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-7-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 56 +++++++++++++++++++++++++++++++--- - include/net/inet_hashtables.h | 49 +++++++++++++++++++++++++++-- - include/net/sock.h | 7 +++-- - include/uapi/linux/bpf.h | 3 -- - net/core/filter.c | 2 -- - net/ipv4/udp.c | 8 +++-- - net/ipv6/udp.c | 8 +++-- - tools/include/uapi/linux/bpf.h | 3 -- - 8 files changed, 115 insertions(+), 21 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index f89320b6fee31..475e672b4facc 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -94,6 +94,46 @@ static inline struct sock *__inet6_lookup(struct net *net, - daddr, hnum, dif, sdif); - } - -+static inline -+struct sock *inet6_steal_sock(struct net *net, struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, const __be16 sport, -+ const struct in6_addr *daddr, const __be16 dport, -+ bool *refcounted, inet6_ehashfn_t *ehashfn) -+{ -+ struct sock *sk, *reuse_sk; -+ bool prefetched; -+ -+ sk = skb_steal_sock(skb, refcounted, &prefetched); -+ if (!sk) -+ return NULL; -+ -+ if (!prefetched) -+ return sk; -+ -+ if (sk->sk_protocol == IPPROTO_TCP) { -+ if (sk->sk_state != TCP_LISTEN) -+ return sk; -+ } else if (sk->sk_protocol == IPPROTO_UDP) { -+ if (sk->sk_state != TCP_CLOSE) -+ return sk; -+ } else { -+ return sk; -+ } -+ -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, ntohs(dport), -+ ehashfn); -+ if (!reuse_sk) -+ return sk; -+ -+ /* We've chosen a new reuseport sock which is never refcounted. This -+ * implies that sk also isn't refcounted. -+ */ -+ WARN_ON_ONCE(*refcounted); -+ -+ return reuse_sk; -+} -+ - static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, - struct sk_buff *skb, int doff, - const __be16 sport, -@@ -101,14 +141,20 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, - int iif, int sdif, - bool *refcounted) - { -- struct sock *sk = skb_steal_sock(skb, refcounted); -- -+ struct net *net = dev_net(skb_dst(skb)->dev); -+ const struct ipv6hdr *ip6h = ipv6_hdr(skb); -+ struct sock *sk; -+ -+ sk = inet6_steal_sock(net, skb, doff, &ip6h->saddr, sport, &ip6h->daddr, dport, -+ refcounted, inet6_ehashfn); -+ if (IS_ERR(sk)) -+ return NULL; - if (sk) - return sk; - -- return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, -- doff, &ipv6_hdr(skb)->saddr, sport, -- &ipv6_hdr(skb)->daddr, ntohs(dport), -+ return __inet6_lookup(net, hashinfo, skb, -+ doff, &ip6h->saddr, sport, -+ &ip6h->daddr, ntohs(dport), - iif, sdif, refcounted); - } - -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index ddfa2e67fdb51..a1b8eb147ce73 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -442,6 +442,46 @@ static inline struct sock *inet_lookup(struct net *net, - return sk; - } - -+static inline -+struct sock *inet_steal_sock(struct net *net, struct sk_buff *skb, int doff, -+ const __be32 saddr, const __be16 sport, -+ const __be32 daddr, const __be16 dport, -+ bool *refcounted, inet_ehashfn_t *ehashfn) -+{ -+ struct sock *sk, *reuse_sk; -+ bool prefetched; -+ -+ sk = skb_steal_sock(skb, refcounted, &prefetched); -+ if (!sk) -+ return NULL; -+ -+ if (!prefetched) -+ return sk; -+ -+ if (sk->sk_protocol == IPPROTO_TCP) { -+ if (sk->sk_state != TCP_LISTEN) -+ return sk; -+ } else if (sk->sk_protocol == IPPROTO_UDP) { -+ if (sk->sk_state != TCP_CLOSE) -+ return sk; -+ } else { -+ return sk; -+ } -+ -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, ntohs(dport), -+ ehashfn); -+ if (!reuse_sk) -+ return sk; -+ -+ /* We've chosen a new reuseport sock which is never refcounted. This -+ * implies that sk also isn't refcounted. -+ */ -+ WARN_ON_ONCE(*refcounted); -+ -+ return reuse_sk; -+} -+ - static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - struct sk_buff *skb, - int doff, -@@ -450,13 +490,18 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - const int sdif, - bool *refcounted) - { -- struct sock *sk = skb_steal_sock(skb, refcounted); -+ struct net *net = dev_net(skb_dst(skb)->dev); - const struct iphdr *iph = ip_hdr(skb); -+ struct sock *sk; - -+ sk = inet_steal_sock(net, skb, doff, iph->saddr, sport, iph->daddr, dport, -+ refcounted, inet_ehashfn); -+ if (IS_ERR(sk)) -+ return NULL; - if (sk) - return sk; - -- return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb, -+ return __inet_lookup(net, hashinfo, skb, - doff, iph->saddr, sport, - iph->daddr, dport, inet_iif(skb), sdif, - refcounted); -diff --git a/include/net/sock.h b/include/net/sock.h -index e8927f2d47a3c..11d503417591e 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -2822,20 +2822,23 @@ sk_is_refcounted(struct sock *sk) - * skb_steal_sock - steal a socket from an sk_buff - * @skb: sk_buff to steal the socket from - * @refcounted: is set to true if the socket is reference-counted -+ * @prefetched: is set to true if the socket was assigned from bpf - */ - static inline struct sock * --skb_steal_sock(struct sk_buff *skb, bool *refcounted) -+skb_steal_sock(struct sk_buff *skb, bool *refcounted, bool *prefetched) - { - if (skb->sk) { - struct sock *sk = skb->sk; - - *refcounted = true; -- if (skb_sk_is_prefetched(skb)) -+ *prefetched = skb_sk_is_prefetched(skb); -+ if (*prefetched) - *refcounted = sk_is_refcounted(sk); - skb->destructor = NULL; - skb->sk = NULL; - return sk; - } -+ *prefetched = false; - *refcounted = false; - return NULL; - } -diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h -index 60a9d59beeabb..d8cbae8220256 100644 ---- a/include/uapi/linux/bpf.h -+++ b/include/uapi/linux/bpf.h -@@ -4159,9 +4159,6 @@ union bpf_attr { - * **-EOPNOTSUPP** if the operation is not supported, for example - * a call from outside of TC ingress. - * -- * **-ESOCKTNOSUPPORT** if the socket type is not supported -- * (reuseport). -- * - * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags) - * Description - * Helper is overloaded depending on BPF program type. This -diff --git a/net/core/filter.c b/net/core/filter.c -index f1a5775400658..454da3538965a 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -7350,8 +7350,6 @@ BPF_CALL_3(bpf_sk_assign, struct sk_buff *, skb, struct sock *, sk, u64, flags) - return -EOPNOTSUPP; - if (unlikely(dev_net(skb->dev) != sock_net(sk))) - return -ENETUNREACH; -- if (unlikely(sk_fullsock(sk) && sk->sk_reuseport)) -- return -ESOCKTNOSUPPORT; - if (sk_unhashed(sk)) - return -EOPNOTSUPP; - if (sk_is_refcounted(sk) && -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index fd06e0e34bda3..f8b0fecc10659 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -2414,7 +2414,11 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - if (udp4_csum_init(skb, uh, proto)) - goto csum_error; - -- sk = skb_steal_sock(skb, &refcounted); -+ sk = inet_steal_sock(net, skb, sizeof(struct udphdr), saddr, uh->source, daddr, uh->dest, -+ &refcounted, udp_ehashfn); -+ if (IS_ERR(sk)) -+ goto no_sk; -+ - if (sk) { - struct dst_entry *dst = skb_dst(skb); - int ret; -@@ -2435,7 +2439,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable); - if (sk) - return udp_unicast_rcv_skb(sk, skb, uh); -- -+no_sk: - if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) - goto drop; - nf_reset_ct(skb); -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index a4b124e4bd3b4..82fdc69ee0813 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -992,7 +992,11 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - goto csum_error; - - /* Check if the socket is already available, e.g. due to early demux */ -- sk = skb_steal_sock(skb, &refcounted); -+ sk = inet6_steal_sock(net, skb, sizeof(struct udphdr), saddr, uh->source, daddr, uh->dest, -+ &refcounted, udp6_ehashfn); -+ if (IS_ERR(sk)) -+ goto no_sk; -+ - if (sk) { - struct dst_entry *dst = skb_dst(skb); - int ret; -@@ -1026,7 +1030,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - goto report_csum_error; - return udp6_unicast_rcv_skb(sk, skb, uh); - } -- -+no_sk: - reason = SKB_DROP_REASON_NO_SOCKET; - - if (!uh->check) -diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h -index 60a9d59beeabb..d8cbae8220256 100644 ---- a/tools/include/uapi/linux/bpf.h -+++ b/tools/include/uapi/linux/bpf.h -@@ -4159,9 +4159,6 @@ union bpf_attr { - * **-EOPNOTSUPP** if the operation is not supported, for example - * a call from outside of TC ingress. - * -- * **-ESOCKTNOSUPPORT** if the socket type is not supported -- * (reuseport). -- * - * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags) - * Description - * Helper is overloaded depending on BPF program type. This --- -2.40.1 - diff --git a/queue-6.5/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch b/queue-6.5/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch deleted file mode 100644 index 22d46886874..00000000000 --- a/queue-6.5/net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 298fb569a0325974eb1bdd1b42d09794e5302728 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:07 +0200 -Subject: net: export inet_lookup_reuseport and inet6_lookup_reuseport - -From: Lorenz Bauer - -[ Upstream commit ce796e60b3b196b61fcc565df195443cbb846ef0 ] - -Rename the existing reuseport helpers for IPv4 and IPv6 so that they -can be invoked in the follow up commit. Export them so that building -DCCP and IPv6 as a module works. - -No change in functionality. - -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-3-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Stable-dep-of: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 7 +++++++ - include/net/inet_hashtables.h | 5 +++++ - net/ipv4/inet_hashtables.c | 15 ++++++++------- - net/ipv6/inet6_hashtables.c | 19 ++++++++++--------- - 4 files changed, 30 insertions(+), 16 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 56f1286583d3c..032ddab48f8f8 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -48,6 +48,13 @@ struct sock *__inet6_lookup_established(struct net *net, - const u16 hnum, const int dif, - const int sdif); - -+struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, -+ __be16 sport, -+ const struct in6_addr *daddr, -+ unsigned short hnum); -+ - struct sock *inet6_lookup_listener(struct net *net, - struct inet_hashinfo *hashinfo, - struct sk_buff *skb, int doff, -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index 99bd823e97f62..8734f3488f5d0 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -379,6 +379,11 @@ struct sock *__inet_lookup_established(struct net *net, - const __be32 daddr, const u16 hnum, - const int dif, const int sdif); - -+struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ __be32 saddr, __be16 sport, -+ __be32 daddr, unsigned short hnum); -+ - static inline struct sock * - inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, - const __be32 saddr, const __be16 sport, -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index 0819d6001b9ab..ecb838460629e 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -332,10 +332,10 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - --static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, int doff, -- __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) -+struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ __be32 saddr, __be16 sport, -+ __be32 daddr, unsigned short hnum) - { - struct sock *reuse_sk = NULL; - u32 phash; -@@ -346,6 +346,7 @@ static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, - } - return reuse_sk; - } -+EXPORT_SYMBOL_GPL(inet_lookup_reuseport); - - /* - * Here are some nice properties to exploit here. The BSD API -@@ -369,8 +370,8 @@ static struct sock *inet_lhash2_lookup(struct net *net, - sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) { - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { -- result = lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ result = inet_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum); - if (result) - return result; - -@@ -399,7 +400,7 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c -index b64b49012655e..b7c56867314ed 100644 ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -111,12 +111,12 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - --static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, int doff, -- const struct in6_addr *saddr, -- __be16 sport, -- const struct in6_addr *daddr, -- unsigned short hnum) -+struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, -+ struct sk_buff *skb, int doff, -+ const struct in6_addr *saddr, -+ __be16 sport, -+ const struct in6_addr *daddr, -+ unsigned short hnum) - { - struct sock *reuse_sk = NULL; - u32 phash; -@@ -127,6 +127,7 @@ static inline struct sock *lookup_reuseport(struct net *net, struct sock *sk, - } - return reuse_sk; - } -+EXPORT_SYMBOL_GPL(inet6_lookup_reuseport); - - /* called with rcu_read_lock() */ - static struct sock *inet6_lhash2_lookup(struct net *net, -@@ -143,8 +144,8 @@ static struct sock *inet6_lhash2_lookup(struct net *net, - sk_nulls_for_each_rcu(sk, node, &ilb2->nulls_head) { - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { -- result = lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ result = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum); - if (result) - return result; - -@@ -175,7 +176,7 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); - if (reuse_sk) - sk = reuse_sk; - return sk; --- -2.40.1 - diff --git a/queue-6.5/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch b/queue-6.5/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch deleted file mode 100644 index 4321f9c2f86..00000000000 --- a/queue-6.5/net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch +++ /dev/null @@ -1,63 +0,0 @@ -From bce242512ea4d551c42372ff4c01a8e11e7c23ff Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 15 Aug 2023 09:53:41 +0100 -Subject: net: Fix slab-out-of-bounds in inet[6]_steal_sock - -From: Lorenz Bauer - -[ Upstream commit 8897562f67b3e61ad736cd5c9f307447d33280e4 ] - -Kumar reported a KASAN splat in tcp_v6_rcv: - - bash-5.2# ./test_progs -t btf_skc_cls_ingress - ... - [ 51.810085] BUG: KASAN: slab-out-of-bounds in tcp_v6_rcv+0x2d7d/0x3440 - [ 51.810458] Read of size 2 at addr ffff8881053f038c by task test_progs/226 - -The problem is that inet[6]_steal_sock accesses sk->sk_protocol without -accounting for request or timewait sockets. To fix this we can't just -check sock_common->skc_reuseport since that flag is present on timewait -sockets. - -Instead, add a fullsock check to avoid the out of bands access of sk_protocol. - -Fixes: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Reported-by: Kumar Kartikeya Dwivedi -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230815-bpf-next-v2-1-95126eaa4c1b@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 2 +- - include/net/inet_hashtables.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 475e672b4facc..12780b8fb5630 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -107,7 +107,7 @@ struct sock *inet6_steal_sock(struct net *net, struct sk_buff *skb, int doff, - if (!sk) - return NULL; - -- if (!prefetched) -+ if (!prefetched || !sk_fullsock(sk)) - return sk; - - if (sk->sk_protocol == IPPROTO_TCP) { -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index a1b8eb147ce73..9414cb4e6e624 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -455,7 +455,7 @@ struct sock *inet_steal_sock(struct net *net, struct sk_buff *skb, int doff, - if (!sk) - return NULL; - -- if (!prefetched) -+ if (!prefetched || !sk_fullsock(sk)) - return sk; - - if (sk->sk_protocol == IPPROTO_TCP) { --- -2.40.1 - diff --git a/queue-6.5/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch b/queue-6.5/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch deleted file mode 100644 index e9b0430a816..00000000000 --- a/queue-6.5/net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 74bdfab4fd7c641e55f7fe9d1be9687eeb01df67 Mon Sep 17 00:00:00 2001 -From: Lorenz Bauer -Date: Mon, 31 Jul 2023 11:42:53 +0200 -Subject: net: remove duplicate INDIRECT_CALLABLE_DECLARE of udp[6]_ehashfn - -From: Lorenz Bauer - -commit 74bdfab4fd7c641e55f7fe9d1be9687eeb01df67 upstream. - -There are already INDIRECT_CALLABLE_DECLARE in the hashtable -headers, no need to declare them again. - -Fixes: 0f495f761722 ("net: remove duplicate reuseport_lookup functions") -Suggested-by: Martin Lau -Signed-off-by: Lorenz Bauer -Reviewed-by: Kuniyuki Iwashima -Link: https://lore.kernel.org/r/20230731-indir-call-v1-1-4cd0aeaee64f@isovalent.com -Signed-off-by: Martin KaFai Lau -Signed-off-by: Greg Kroah-Hartman ---- - net/ipv4/inet_hashtables.c | 2 -- - net/ipv6/inet6_hashtables.c | 2 -- - 2 files changed, 4 deletions(-) - ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -333,8 +333,6 @@ static inline int compute_score(struct s - return score; - } - --INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -- - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -112,8 +112,6 @@ static inline int compute_score(struct s - return score; - } - --INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -- - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, diff --git a/queue-6.5/net-remove-duplicate-reuseport_lookup-functions.patch b/queue-6.5/net-remove-duplicate-reuseport_lookup-functions.patch deleted file mode 100644 index 74180fedc63..00000000000 --- a/queue-6.5/net-remove-duplicate-reuseport_lookup-functions.patch +++ /dev/null @@ -1,365 +0,0 @@ -From 67de62b8bc6b539a86c5ad60349474c2847683f5 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Jul 2023 17:30:08 +0200 -Subject: net: remove duplicate reuseport_lookup functions - -From: Lorenz Bauer - -[ Upstream commit 0f495f7617229772403e683033abc473f0f0553c ] - -There are currently four copies of reuseport_lookup: one each for -(TCP, UDP)x(IPv4, IPv6). This forces us to duplicate all callers of -those functions as well. This is already the case for sk_lookup -helpers (inet,inet6,udp4,udp6)_lookup_run_bpf. - -There are two differences between the reuseport_lookup helpers: - -1. They call different hash functions depending on protocol -2. UDP reuseport_lookup checks that sk_state != TCP_ESTABLISHED - -Move the check for sk_state into the caller and use the INDIRECT_CALL -infrastructure to cut down the helpers to one per IP version. - -Reviewed-by: Kuniyuki Iwashima -Signed-off-by: Lorenz Bauer -Link: https://lore.kernel.org/r/20230720-so-reuseport-v6-4-7021b683cdae@isovalent.com -Signed-off-by: Martin KaFai Lau -Stable-dep-of: 9c02bec95954 ("bpf, net: Support SO_REUSEPORT sockets with bpf_sk_assign") -Signed-off-by: Sasha Levin ---- - include/net/inet6_hashtables.h | 11 ++++++++- - include/net/inet_hashtables.h | 15 ++++++++----- - net/ipv4/inet_hashtables.c | 20 +++++++++++------ - net/ipv4/udp.c | 34 +++++++++++----------------- - net/ipv6/inet6_hashtables.c | 14 ++++++++---- - net/ipv6/udp.c | 41 +++++++++++++--------------------- - 6 files changed, 72 insertions(+), 63 deletions(-) - -diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h -index 032ddab48f8f8..f89320b6fee31 100644 ---- a/include/net/inet6_hashtables.h -+++ b/include/net/inet6_hashtables.h -@@ -48,12 +48,21 @@ struct sock *__inet6_lookup_established(struct net *net, - const u16 hnum, const int dif, - const int sdif); - -+typedef u32 (inet6_ehashfn_t)(const struct net *net, -+ const struct in6_addr *laddr, const u16 lport, -+ const struct in6_addr *faddr, const __be16 fport); -+ -+inet6_ehashfn_t inet6_ehashfn; -+ -+INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -+ - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, - __be16 sport, - const struct in6_addr *daddr, -- unsigned short hnum); -+ unsigned short hnum, -+ inet6_ehashfn_t *ehashfn); - - struct sock *inet6_lookup_listener(struct net *net, - struct inet_hashinfo *hashinfo, -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index 8734f3488f5d0..ddfa2e67fdb51 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -379,10 +379,19 @@ struct sock *__inet_lookup_established(struct net *net, - const __be32 daddr, const u16 hnum, - const int dif, const int sdif); - -+typedef u32 (inet_ehashfn_t)(const struct net *net, -+ const __be32 laddr, const __u16 lport, -+ const __be32 faddr, const __be16 fport); -+ -+inet_ehashfn_t inet_ehashfn; -+ -+INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -+ - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum); -+ __be32 daddr, unsigned short hnum, -+ inet_ehashfn_t *ehashfn); - - static inline struct sock * - inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, -@@ -453,10 +462,6 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, - refcounted); - } - --u32 inet6_ehashfn(const struct net *net, -- const struct in6_addr *laddr, const u16 lport, -- const struct in6_addr *faddr, const __be16 fport); -- - static inline void sk_daddr_set(struct sock *sk, __be32 addr) - { - sk->sk_daddr = addr; /* alias of inet_daddr */ -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index ecb838460629e..0a7a726464d9d 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -28,9 +28,9 @@ - #include - #include - --static u32 inet_ehashfn(const struct net *net, const __be32 laddr, -- const __u16 lport, const __be32 faddr, -- const __be16 fport) -+u32 inet_ehashfn(const struct net *net, const __be32 laddr, -+ const __u16 lport, const __be32 faddr, -+ const __be16 fport) - { - static u32 inet_ehash_secret __read_mostly; - -@@ -39,6 +39,7 @@ static u32 inet_ehashfn(const struct net *net, const __be32 laddr, - return __inet_ehashfn(laddr, lport, faddr, fport, - inet_ehash_secret + net_hash_mix(net)); - } -+EXPORT_SYMBOL_GPL(inet_ehashfn); - - /* This function handles inet_sock, but also timewait and request sockets - * for IPv4/IPv6. -@@ -332,16 +333,20 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - -+INDIRECT_CALLABLE_DECLARE(inet_ehashfn_t udp_ehashfn); -+ - struct sock *inet_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) -+ __be32 daddr, unsigned short hnum, -+ inet_ehashfn_t *ehashfn) - { - struct sock *reuse_sk = NULL; - u32 phash; - - if (sk->sk_reuseport) { -- phash = inet_ehashfn(net, daddr, hnum, saddr, sport); -+ phash = INDIRECT_CALL_2(ehashfn, udp_ehashfn, inet_ehashfn, -+ net, daddr, hnum, saddr, sport); - reuse_sk = reuseport_select_sock(sk, phash, skb, doff); - } - return reuse_sk; -@@ -371,7 +376,7 @@ static struct sock *inet_lhash2_lookup(struct net *net, - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { - result = inet_lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ saddr, sport, daddr, hnum, inet_ehashfn); - if (result) - return result; - -@@ -400,7 +405,8 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum, -+ inet_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index b3aa68ea29de2..fd06e0e34bda3 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -407,9 +407,9 @@ static int compute_score(struct sock *sk, struct net *net, - return score; - } - --static u32 udp_ehashfn(const struct net *net, const __be32 laddr, -- const __u16 lport, const __be32 faddr, -- const __be16 fport) -+INDIRECT_CALLABLE_SCOPE -+u32 udp_ehashfn(const struct net *net, const __be32 laddr, const __u16 lport, -+ const __be32 faddr, const __be16 fport) - { - static u32 udp_ehash_secret __read_mostly; - -@@ -419,22 +419,6 @@ static u32 udp_ehashfn(const struct net *net, const __be32 laddr, - udp_ehash_secret + net_hash_mix(net)); - } - --static struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, -- __be32 saddr, __be16 sport, -- __be32 daddr, unsigned short hnum) --{ -- struct sock *reuse_sk = NULL; -- u32 hash; -- -- if (sk->sk_reuseport && sk->sk_state != TCP_ESTABLISHED) { -- hash = udp_ehashfn(net, daddr, hnum, saddr, sport); -- reuse_sk = reuseport_select_sock(sk, hash, skb, -- sizeof(struct udphdr)); -- } -- return reuse_sk; --} -- - /* called with rcu_read_lock() */ - static struct sock *udp4_lib_lookup2(struct net *net, - __be32 saddr, __be16 sport, -@@ -453,7 +437,14 @@ static struct sock *udp4_lib_lookup2(struct net *net, - daddr, hnum, dif, sdif); - if (score > badness) { - badness = score; -- result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ -+ if (sk->sk_state == TCP_ESTABLISHED) { -+ result = sk; -+ continue; -+ } -+ -+ result = inet_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp_ehashfn); - if (!result) { - result = sk; - continue; -@@ -492,7 +483,8 @@ static struct sock *udp4_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ reuse_sk = inet_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c -index b7c56867314ed..3616225c89ef6 100644 ---- a/net/ipv6/inet6_hashtables.c -+++ b/net/ipv6/inet6_hashtables.c -@@ -39,6 +39,7 @@ u32 inet6_ehashfn(const struct net *net, - return __inet6_ehashfn(lhash, lport, fhash, fport, - inet6_ehash_secret + net_hash_mix(net)); - } -+EXPORT_SYMBOL_GPL(inet6_ehashfn); - - /* - * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so -@@ -111,18 +112,22 @@ static inline int compute_score(struct sock *sk, struct net *net, - return score; - } - -+INDIRECT_CALLABLE_DECLARE(inet6_ehashfn_t udp6_ehashfn); -+ - struct sock *inet6_lookup_reuseport(struct net *net, struct sock *sk, - struct sk_buff *skb, int doff, - const struct in6_addr *saddr, - __be16 sport, - const struct in6_addr *daddr, -- unsigned short hnum) -+ unsigned short hnum, -+ inet6_ehashfn_t *ehashfn) - { - struct sock *reuse_sk = NULL; - u32 phash; - - if (sk->sk_reuseport) { -- phash = inet6_ehashfn(net, daddr, hnum, saddr, sport); -+ phash = INDIRECT_CALL_INET(ehashfn, udp6_ehashfn, inet6_ehashfn, -+ net, daddr, hnum, saddr, sport); - reuse_sk = reuseport_select_sock(sk, phash, skb, doff); - } - return reuse_sk; -@@ -145,7 +150,7 @@ static struct sock *inet6_lhash2_lookup(struct net *net, - score = compute_score(sk, net, hnum, daddr, dif, sdif); - if (score > hiscore) { - result = inet6_lookup_reuseport(net, sk, skb, doff, -- saddr, sport, daddr, hnum); -+ saddr, sport, daddr, hnum, inet6_ehashfn); - if (result) - return result; - -@@ -176,7 +181,8 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, doff, -+ saddr, sport, daddr, hnum, inet6_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index 3ffca158d3e11..a4b124e4bd3b4 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -72,11 +72,12 @@ int udpv6_init_sock(struct sock *sk) - return 0; - } - --static u32 udp6_ehashfn(const struct net *net, -- const struct in6_addr *laddr, -- const u16 lport, -- const struct in6_addr *faddr, -- const __be16 fport) -+INDIRECT_CALLABLE_SCOPE -+u32 udp6_ehashfn(const struct net *net, -+ const struct in6_addr *laddr, -+ const u16 lport, -+ const struct in6_addr *faddr, -+ const __be16 fport) - { - static u32 udp6_ehash_secret __read_mostly; - static u32 udp_ipv6_hash_secret __read_mostly; -@@ -161,24 +162,6 @@ static int compute_score(struct sock *sk, struct net *net, - return score; - } - --static struct sock *lookup_reuseport(struct net *net, struct sock *sk, -- struct sk_buff *skb, -- const struct in6_addr *saddr, -- __be16 sport, -- const struct in6_addr *daddr, -- unsigned int hnum) --{ -- struct sock *reuse_sk = NULL; -- u32 hash; -- -- if (sk->sk_reuseport && sk->sk_state != TCP_ESTABLISHED) { -- hash = udp6_ehashfn(net, daddr, hnum, saddr, sport); -- reuse_sk = reuseport_select_sock(sk, hash, skb, -- sizeof(struct udphdr)); -- } -- return reuse_sk; --} -- - /* called with rcu_read_lock() */ - static struct sock *udp6_lib_lookup2(struct net *net, - const struct in6_addr *saddr, __be16 sport, -@@ -196,7 +179,14 @@ static struct sock *udp6_lib_lookup2(struct net *net, - daddr, hnum, dif, sdif); - if (score > badness) { - badness = score; -- result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ -+ if (sk->sk_state == TCP_ESTABLISHED) { -+ result = sk; -+ continue; -+ } -+ -+ result = inet6_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp6_ehashfn); - if (!result) { - result = sk; - continue; -@@ -236,7 +226,8 @@ static inline struct sock *udp6_lookup_run_bpf(struct net *net, - if (no_reuseport || IS_ERR_OR_NULL(sk)) - return sk; - -- reuse_sk = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ reuse_sk = inet6_lookup_reuseport(net, sk, skb, sizeof(struct udphdr), -+ saddr, sport, daddr, hnum, udp6_ehashfn); - if (reuse_sk) - sk = reuse_sk; - return sk; --- -2.40.1 - diff --git a/queue-6.5/series b/queue-6.5/series index 6ccec073d28..4b13d66d498 100644 --- a/queue-6.5/series +++ b/queue-6.5/series @@ -87,9 +87,6 @@ wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch wifi-mt76-mt7996-fix-wa-event-ring-size.patch udp-re-score-reuseport-groups-when-connected-sockets.patch bpf-reject-unhashed-sockets-in-bpf_sk_assign.patch -net-export-inet_lookup_reuseport-and-inet6_lookup_re.patch -net-remove-duplicate-reuseport_lookup-functions.patch -bpf-net-support-so_reuseport-sockets-with-bpf_sk_ass.patch wifi-mt76-mt7915-fix-command-timeout-in-ap-stop-peri.patch wifi-mt76-mt7915-fix-capabilities-in-non-ap-mode.patch wifi-mt76-mt7915-remove-vht160-capability-on-mt7915.patch @@ -131,7 +128,6 @@ net-pcs-lynx-fix-lynx_pcs_link_up_sgmii-not-doing-an.patch libbpf-set-close-on-exec-flag-on-gzopen.patch selftests-bpf-fix-repeat-option-when-kfunc_call-veri.patch selftests-bpf-clean-up-fmod_ret-in-bench_rename-test.patch -net-fix-slab-out-of-bounds-in-inet-6-_steal_sock.patch net-hns3-move-dump-regs-function-to-a-separate-file.patch net-hns3-support-tlv-in-regs-data-for-hns3-pf-driver.patch net-hns3-fix-wrong-rpu-tln-reg-issue.patch @@ -732,4 +728,3 @@ memfd-do-not-eacces-old-memfd_create-users-with-vm.m.patch memfd-replace-ratcheting-feature-from-vm.memfd_noexe.patch memfd-improve-userspace-warnings-for-missing-exec-re.patch revert-memfd-improve-userspace-warnings-for-missing-exec-related-flags.patch -net-remove-duplicate-indirect_callable_declare-of-udp_ehashfn.patch