> diff --git a/net/core/Makefile b/net/core/Makefile
> index b3fdcb4e355fa..a9295b7859010 100644
> --- a/net/core/Makefile
> +++ b/net/core/Makefile
> @@ -44,6 +44,9 @@ obj-$(CONFIG_FAILOVER) += failover.o
> obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o
> obj-$(CONFIG_BPF_SYSCALL) += sock_map.o
> obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o
> +ifneq ($(CONFIG_INET),)
> +obj-$(CONFIG_BPF_SYSCALL) += bpf_ksock.o
> +endif
> obj-$(CONFIG_OF) += of_net.o
> obj-$(CONFIG_NET_TEST) += net_test.o
> obj-$(CONFIG_NET_DEVMEM) += devmem.o
This isn't a bug, but would 'ifdef CONFIG_INET' be preferable here to
match the rest of net/? There are zero occurrences of 'ifneq
($(CONFIG_...),)' and fourteen occurrences of 'ifdef CONFIG_...' across
net/**/Makefile, and this is the only conditional block in
net/core/Makefile.
> diff --git a/net/core/bpf_ksock.c b/net/core/bpf_ksock.c
> new file mode 100644
> index 0000000000000..d65200679b65d
> --- /dev/null
> +++ b/net/core/bpf_ksock.c
[ ... ]
> +/**
> + * bpf_ksock_connect() - Connect a BPF kernel socket to a remote address.
> + * @ks: The BPF kernel socket context.
> + * @addr: Pointer to an IPv4 or IPv6 socket address.
> + * @addr__sz: Size of the address union.
> + *
> + * Connects the socket to the specified remote address and port.
> + *
> + * This function may sleep while connecting the socket, so it can only be used
> + * in sleepable BPF programs (SYSCALL).
> + *
> + * Return: 0 on success, negative errno on error.
> + */
> +__bpf_kfunc int bpf_ksock_connect(struct bpf_ksock *ks,
> + const union bpf_ksock_addr *addr,
> + u32 addr__sz)
> +{
> + struct sockaddr_storage sa;
> + int addrlen;
> +
> + if (!bpf_ksock_has_user_task_context())
> + return -EOPNOTSUPP;
> +
> + if (!addr || addr__sz != sizeof(*addr))
> + return -EINVAL;
> +
> + /* Kfunc memory arguments may be unaligned. */
> + memcpy(&sa, addr, sizeof(*addr));
> +
> + switch (sa.ss_family) {
> + case AF_INET:
> + addrlen = sizeof(struct sockaddr_in);
> + break;
> +#if IS_ENABLED(CONFIG_IPV6)
> + case AF_INET6:
> + addrlen = sizeof(struct sockaddr_in6);
> + break;
> +#endif
> + default:
> + return -EAFNOSUPPORT;
> + }
> +
> + return connect_socket(ks->sock, &sa, addrlen, 0);
> +}
This isn't a bug, but could the #if IS_ENABLED(CONFIG_IPV6) guard be
dropped? struct sockaddr_in6 is defined unconditionally in
include/uapi/linux/in6.h, and union bpf_ksock_addr in the new header
already references it without a guard. bpf_ksock_create() accepts
opts_copy.family == AF_INET6 unconditionally and relies on sock_create()
to return -EAFNOSUPPORT when IPv6 is not built. With CONFIG_IPV6=n, the
net effect is identical (-EAFNOSUPPORT either way), so dropping the guard
would make bpf_ksock_connect() and bpf_ksock_create() validate families
the same way.
[ ... ]
> +/**
> + * bpf_ksock_send() - Send data through a BPF kernel socket.
> + * @ks: The BPF kernel socket context. Must be an acquired reference.
> + * @data: Pointer to the data to send.
> + * @data__sz: Size of the data to send (max 65535 bytes).
> + *
> + * Sends data on a connected socket, best-effort and nonblocking. This may sleep
> + * (kernel_sendmsg), so it can only be called from sleepable BPF programs.
> + *
> + * Return: Number of bytes sent on success, negative errno on error.
> + */
> +__bpf_kfunc int bpf_ksock_send(struct bpf_ksock *ks, const void *data,
> + u32 data__sz)
> +{
> + struct msghdr msg = {
> + .msg_flags = MSG_DONTWAIT,
> + };
> + struct kvec iov = {
> + .iov_base = (void *)data,
> + .iov_len = data__sz,
> + };
> + int ret;
> +
> + if (!bpf_ksock_has_user_task_context())
> + return -EOPNOTSUPP;
> +
> + /* Early check for UDP. Exact limits enforced by kernel_sendmsg(). */
> + if (data__sz > IP_MAX_MTU)
> + return -EMSGSIZE;
> +
> + ret = kernel_sendmsg(ks->sock, &msg, &iov, 1, data__sz);
> +
> + return ret;
> +}
This isn't a bug, but is the 64K cap intentional for AF_INET6 sockets?
The early size check uses IP_MAX_MTU, an IPv4-specific constant (0xFFFF),
even though bpf_ksock_create() also accepts AF_INET6. udp_sendmsg()
rejects len > 0xFFFF so the bound matches exactly for IPv4, but
udpv6_sendmsg() allows up to INT_MAX - sizeof(struct udphdr), so AF_INET6
sockets are silently capped at 64K by this kfunc rather than by the
protocol. Also, should the comment say udp_sendmsg()/udpv6_sendmsg()
instead of kernel_sendmsg()? kernel_sendmsg() performs no length
validation - the limits come from udp_sendmsg()/udpv6_sendmsg() and
ip_append_data().
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/31618864886
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.