From: Martin KaFai Lau <martin.lau@linux.dev>
To: Jordan Rife <jrife@google.com>, bpf@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org, netdev@vger.kernel.org,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
John Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@kernel.org>,
Stanislav Fomichev <sdf@google.com>, Hao Luo <haoluo@google.com>,
Jiri Olsa <jolsa@kernel.org>, Mykola Lysenko <mykolal@fb.com>,
Shuah Khan <shuah@kernel.org>,
Kui-Feng Lee <thinker.li@gmail.com>,
Artem Savkov <asavkov@redhat.com>,
Dave Marchevsky <davemarchevsky@fb.com>,
Menglong Dong <imagedong@tencent.com>, Daniel Xu <dxu@dxuuu.xyz>,
David Vernet <void@manifault.com>,
Daan De Meyer <daan.j.demeyer@gmail.com>,
Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Subject: Re: [PATCH v2 bpf-next 2/6] selftests/bpf: Implement socket kfuncs for bpf_testmod
Date: Mon, 15 Apr 2024 23:43:06 -0700 [thread overview]
Message-ID: <65b2f4a3-bd8e-495b-adca-1e7adce5301d@linux.dev> (raw)
In-Reply-To: <20240412165230.2009746-3-jrife@google.com>
On 4/12/24 9:52 AM, Jordan Rife wrote:
> This patch adds a set of kfuncs to bpf_testmod that can be used to
> manipulate a socket from kernel space.
>
> Signed-off-by: Jordan Rife <jrife@google.com>
> ---
> .../selftests/bpf/bpf_testmod/bpf_testmod.c | 139 ++++++++++++++++++
> .../bpf/bpf_testmod/bpf_testmod_kfunc.h | 27 ++++
> 2 files changed, 166 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
> index 39ad96a18123f..663df8148097e 100644
> --- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
> +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
> @@ -10,18 +10,29 @@
> #include <linux/percpu-defs.h>
> #include <linux/sysfs.h>
> #include <linux/tracepoint.h>
> +#include <linux/net.h>
> +#include <linux/socket.h>
> +#include <linux/nsproxy.h>
> +#include <linux/inet.h>
> +#include <linux/in.h>
> +#include <linux/in6.h>
> +#include <linux/un.h>
> +#include <net/sock.h>
> #include "bpf_testmod.h"
> #include "bpf_testmod_kfunc.h"
>
> #define CREATE_TRACE_POINTS
> #include "bpf_testmod-events.h"
>
> +#define CONNECT_TIMEOUT_SEC 1
> +
> typedef int (*func_proto_typedef)(long);
> typedef int (*func_proto_typedef_nested1)(func_proto_typedef);
> typedef int (*func_proto_typedef_nested2)(func_proto_typedef_nested1);
>
> DEFINE_PER_CPU(int, bpf_testmod_ksym_percpu) = 123;
> long bpf_testmod_test_struct_arg_result;
> +static struct socket *sock;
>
> struct bpf_testmod_struct_arg_1 {
> int a;
> @@ -494,6 +505,124 @@ __bpf_kfunc static u32 bpf_kfunc_call_test_static_unused_arg(u32 arg, u32 unused
> return arg;
> }
>
> +__bpf_kfunc int bpf_kfunc_init_sock(struct init_sock_args *args)
> +{
> + int proto;
> +
> + if (sock)
> + pr_warn("%s called without releasing old sock", __func__);
hmm...this global sock pointer is quite unease. e.g. what if multiple tasks
trying to use init/close/connect... in parallel.
Storing sock in a bpf map will be better but that may be overkill for testing.
Can a separate global lock/mutex (not the lock_sock) be acquired first before
using the sock pointer in the kfuncs?
> +
> + switch (args->af) {
> + case AF_INET:
> + case AF_INET6:
> + proto = args->type == SOCK_STREAM ? IPPROTO_TCP : IPPROTO_UDP;
> + break;
> + case AF_UNIX:
> + proto = PF_UNIX;
> + break;
> + default:
> + pr_err("invalid address family %d\n", args->af);
> + return -EINVAL;
> + }
> +
> + return sock_create_kern(&init_net, args->af, args->type, proto, &sock);
> +}
> +
> +__bpf_kfunc void bpf_kfunc_close_sock(void)
> +{
> + if (sock) {
> + sock_release(sock);
bpf_testmod_exit() should probably do this NULL check and sock_release() also.
> + sock = NULL;
> + }
> +}
> +
> +__bpf_kfunc int bpf_kfunc_call_kernel_connect(struct addr_args *args)
> +{
> + /* Set timeout for call to kernel_connect() to prevent it from hanging,
> + * and consider the connection attempt failed if it returns
> + * -EINPROGRESS.
> + */
> + sock->sk->sk_sndtimeo = CONNECT_TIMEOUT_SEC * HZ;
Is it better to set sk_sndtimeo in bpf_kfunc_init_sock() ?
> +
> + return kernel_connect(sock, (struct sockaddr *)&args->addr,
> + args->addrlen, 0);
> +}
> +
> +__bpf_kfunc int bpf_kfunc_call_kernel_bind(struct addr_args *args)
> +{
> + return kernel_bind(sock, (struct sockaddr *)&args->addr, args->addrlen);
> +}
> +
> +__bpf_kfunc int bpf_kfunc_call_kernel_listen(void)
> +{
> + return kernel_listen(sock, 128);
> +}
> +
> +__bpf_kfunc int bpf_kfunc_call_kernel_sendmsg(struct sendmsg_args *args)
> +{
> + struct msghdr msg = {
> + .msg_name = &args->addr.addr,
> + .msg_namelen = args->addr.addrlen,
> + };
> + struct kvec iov;
> + int err;
> +
> + iov.iov_base = args->msg;
> + iov.iov_len = args->msglen;
> +
> + err = kernel_sendmsg(sock, &msg, &iov, 1, args->msglen);
> + args->addr.addrlen = msg.msg_namelen;
> +
> + return err;
> +}
> +
> +__bpf_kfunc int bpf_kfunc_call_sock_sendmsg(struct sendmsg_args *args)
> +{
> + struct msghdr msg = {
> + .msg_name = &args->addr.addr,
> + .msg_namelen = args->addr.addrlen,
> + };
> + struct kvec iov;
> + int err;
> +
> + iov.iov_base = args->msg;
> + iov.iov_len = args->msglen;
> +
> + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &iov, 1, args->msglen);
> + err = sock_sendmsg(sock, &msg);
> + args->addr.addrlen = msg.msg_namelen;
> +
> + return err;
> +}
> +
> +__bpf_kfunc int bpf_kfunc_call_kernel_getsockname(struct addr_args *args)
> +{
> + int err;
> +
> + err = kernel_getsockname(sock, (struct sockaddr *)&args->addr);
> + if (err < 0)
> + goto out;
> +
> + args->addrlen = err;
> + err = 0;
> +out:
> + return err;
> +}
> +
> +__bpf_kfunc int bpf_kfunc_call_kernel_getpeername(struct addr_args *args)
> +{
> + int err;
> +
> + err = kernel_getpeername(sock, (struct sockaddr *)&args->addr);
> + if (err < 0)
> + goto out;
> +
> + args->addrlen = err;
> + err = 0;
> +out:
> + return err;
> +}
> +
> BTF_KFUNCS_START(bpf_testmod_check_kfunc_ids)
> BTF_ID_FLAGS(func, bpf_testmod_test_mod_kfunc)
> BTF_ID_FLAGS(func, bpf_kfunc_call_test1)
> @@ -520,6 +649,15 @@ BTF_ID_FLAGS(func, bpf_kfunc_call_test_ref, KF_TRUSTED_ARGS | KF_RCU)
> BTF_ID_FLAGS(func, bpf_kfunc_call_test_destructive, KF_DESTRUCTIVE)
> BTF_ID_FLAGS(func, bpf_kfunc_call_test_static_unused_arg)
> BTF_ID_FLAGS(func, bpf_kfunc_call_test_offset)
> +BTF_ID_FLAGS(func, bpf_kfunc_init_sock)
> +BTF_ID_FLAGS(func, bpf_kfunc_close_sock)
> +BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_connect)
> +BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_bind)
> +BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_listen)
> +BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_sendmsg)
> +BTF_ID_FLAGS(func, bpf_kfunc_call_sock_sendmsg)
> +BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_getsockname)
> +BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_getpeername)
All these new kfunc should have the KF_SLEEPABLE flag.
> BTF_KFUNCS_END(bpf_testmod_check_kfunc_ids)
>
> static int bpf_testmod_ops_init(struct btf *btf)
> @@ -650,6 +788,7 @@ static int bpf_testmod_init(void)
> return ret;
> if (bpf_fentry_test1(0) < 0)
> return -EINVAL;
> + sock = NULL;
> return sysfs_create_bin_file(kernel_kobj, &bin_attr_bpf_testmod_file);
> }
>
> diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_kfunc.h b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_kfunc.h
> index 7c664dd610597..cdf7769a7d8ca 100644
> --- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_kfunc.h
> +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_kfunc.h
> @@ -64,6 +64,22 @@ struct prog_test_fail3 {
> char arr2[];
> };
>
> +struct init_sock_args {
> + int af;
> + int type;
> +};
> +
> +struct addr_args {
> + char addr[sizeof(struct __kernel_sockaddr_storage)];
nit. Can "struct sockaddr_storage addr;" be directly used instead of a char array?
> + int addrlen;
> +};
> +
> +struct sendmsg_args {
> + struct addr_args addr;
> + char msg[10];
> + int msglen;
> +};
> +
> struct prog_test_ref_kfunc *
> bpf_kfunc_call_test_acquire(unsigned long *scalar_ptr) __ksym;
> void bpf_kfunc_call_test_release(struct prog_test_ref_kfunc *p) __ksym;
> @@ -106,4 +122,15 @@ void bpf_kfunc_call_test_fail3(struct prog_test_fail3 *p);
> void bpf_kfunc_call_test_mem_len_fail1(void *mem, int len);
>
> void bpf_kfunc_common_test(void) __ksym;
> +
> +int bpf_kfunc_init_sock(struct init_sock_args *args) __ksym;
> +void bpf_kfunc_close_sock(void) __ksym;
> +int bpf_kfunc_call_kernel_connect(struct addr_args *args) __ksym;
> +int bpf_kfunc_call_kernel_bind(struct addr_args *args) __ksym;
> +int bpf_kfunc_call_kernel_listen(void) __ksym;
> +int bpf_kfunc_call_kernel_sendmsg(struct sendmsg_args *args) __ksym;
> +int bpf_kfunc_call_sock_sendmsg(struct sendmsg_args *args) __ksym;
> +int bpf_kfunc_call_kernel_getsockname(struct addr_args *args) __ksym;
> +int bpf_kfunc_call_kernel_getpeername(struct addr_args *args) __ksym;
> +
> #endif /* _BPF_TESTMOD_KFUNC_H */
next prev parent reply other threads:[~2024-04-16 6:43 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-12 16:52 [PATCH v2 bpf-next 0/6] selftests/bpf: Add sockaddr tests for kernel networking Jordan Rife
2024-04-12 16:52 ` [PATCH v2 bpf-next 1/6] selftests/bpf: Fix bind program for big endian systems Jordan Rife
2024-04-13 1:01 ` Kui-Feng Lee
2024-04-13 1:19 ` Jordan Rife
[not found] ` <CADKFtnR4qtPV4OP_Y04+ON+bKc8uPxxLZF3cTj-0YCupD6y06A@mail.gmail.com>
2024-04-13 1:28 ` Kui-Feng Lee
2024-04-12 16:52 ` [PATCH v2 bpf-next 2/6] selftests/bpf: Implement socket kfuncs for bpf_testmod Jordan Rife
2024-04-13 1:26 ` Kui-Feng Lee
2024-04-15 15:34 ` Jordan Rife
2024-04-16 6:43 ` Martin KaFai Lau [this message]
2024-04-17 16:59 ` Jordan Rife
2024-05-01 21:54 ` Kui-Feng Lee
2024-04-12 16:52 ` [PATCH v2 bpf-next 3/6] selftests/bpf: Implement BPF programs for kernel socket operations Jordan Rife
2024-04-12 16:52 ` [PATCH v2 bpf-next 4/6] selftests/bpf: Add IPv4 and IPv6 sockaddr test cases Jordan Rife
2024-04-16 6:07 ` Martin KaFai Lau
2024-04-16 6:47 ` Martin KaFai Lau
2024-04-17 17:08 ` Jordan Rife
2024-04-18 0:49 ` Martin KaFai Lau
2024-04-18 16:37 ` Jordan Rife
2024-04-22 21:14 ` Martin KaFai Lau
2024-04-28 17:47 ` Jordan Rife
2024-04-29 17:40 ` Martin KaFai Lau
2024-04-29 21:47 ` Jordan Rife
2024-04-12 16:52 ` [PATCH v2 bpf-next 5/6] selftests/bpf: Make sock configurable for each test case Jordan Rife
2024-04-12 16:52 ` [PATCH v2 bpf-next 6/6] selftests/bpf: Add kernel socket operation tests Jordan Rife
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=65b2f4a3-bd8e-495b-adca-1e7adce5301d@linux.dev \
--to=martin.lau@linux.dev \
--cc=andrii@kernel.org \
--cc=asavkov@redhat.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daan.j.demeyer@gmail.com \
--cc=daniel@iogearbox.net \
--cc=davemarchevsky@fb.com \
--cc=dxu@dxuuu.xyz \
--cc=eddyz87@gmail.com \
--cc=haoluo@google.com \
--cc=imagedong@tencent.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=jrife@google.com \
--cc=kpsingh@kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mykolal@fb.com \
--cc=netdev@vger.kernel.org \
--cc=sdf@google.com \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=thinker.li@gmail.com \
--cc=void@manifault.com \
--cc=willemdebruijn.kernel@gmail.com \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.