From: Leon Hwang Date: Sat, 13 Jun 2026 16:24:42 +0000 (+0800) Subject: bpf: Fix bpf_get/setsockopt to tos for ipv4-mapped ipv6 socket X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ca0f587c029afa66227f7b932450b1c417403394;p=thirdparty%2Flinux.git bpf: Fix bpf_get/setsockopt to tos for ipv4-mapped ipv6 socket When TCP over IPv4 via INET6 API, bpf_get/setsockopt with ipv4 will fail, because sk->sk_family is AF_INET6. With ipv6 will success, not take effect, because inet_csk(sk)->icsk_af_ops is ipv6_mapped and use ip_queue_xmit, inet_sk(sk)->tos. To relax this restriction, allow getting/setting tos for those possible ipv4-mapped ipv6 sockets. Fixes: ee7f1e1302f5 ("bpf: Change bpf_setsockopt(SOL_IP) to reuse do_ip_setsockopt()") Signed-off-by: Feng Zhou Signed-off-by: Leon Hwang Link: https://lore.kernel.org/r/20260613162443.60515-2-leon.hwang@linux.dev Signed-off-by: Alexei Starovoitov --- diff --git a/net/core/filter.c b/net/core/filter.c index 9590877b0714..57b00c6cc8cc 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -5544,11 +5544,24 @@ static int sol_tcp_sockopt(struct sock *sk, int optname, KERNEL_SOCKPTR(optval), *optlen); } +static bool sk_allows_sol_ip_sockopt(struct sock *sk) +{ + switch (sk->sk_family) { + case AF_INET: + return true; + case AF_INET6: + /* Allow getting/setting sockopt for possible ipv4-mapped ipv6 socket. */ + return sk->sk_type != SOCK_RAW && !ipv6_only_sock(sk); + default: + return false; + } +} + static int sol_ip_sockopt(struct sock *sk, int optname, char *optval, int *optlen, bool getopt) { - if (sk->sk_family != AF_INET) + if (!sk_allows_sol_ip_sockopt(sk)) return -EINVAL; switch (optname) {