Reuse the existing basic ksock test to also bind to a specific source and verify that the source address was respected when receiving. Signed-off-by: Mahe Tardy --- .../testing/selftests/bpf/prog_tests/ksock.c | 22 ++++++++++++++----- .../selftests/bpf/progs/ksock_common.h | 2 ++ tools/testing/selftests/bpf/progs/ksock_lsm.c | 18 +++++++++++---- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/ksock.c b/tools/testing/selftests/bpf/prog_tests/ksock.c index dd6b167623d9..9827aeccf3f5 100644 --- a/tools/testing/selftests/bpf/prog_tests/ksock.c +++ b/tools/testing/selftests/bpf/prog_tests/ksock.c @@ -10,6 +10,7 @@ #define NS_TEST "ksock_lsm_ns" #define RECV_PORT 7777 +#define LOCAL_KSOCK_PORT 6666 #define RECV_TIMEOUT_SEC 5 struct ksock_test_env { @@ -63,6 +64,8 @@ void test_ksock_lsm(void) .sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK), }; + struct sockaddr_in src_addr = {}; + socklen_t src_addrlen = sizeof(src_addr); struct ksock_lsm *skel; char recv_data[sizeof(skel->data->send_data)] = {}; ssize_t n; @@ -76,9 +79,10 @@ void test_ksock_lsm(void) if (!ksock_test_env_setup(&env)) goto fail; - /* Step 1: Run the setup SYSCALL prog to create the ksock */ + /* Step 1: Create, bind, and connect the ksock from the SYSCALL prog. */ skel->bss->ipv4_remote = htonl(INADDR_LOOPBACK); skel->bss->remote_port = RECV_PORT; + skel->bss->local_port = LOCAL_KSOCK_PORT; err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.ksock_setup), &opts); if (!ASSERT_OK(err, "ksock_setup run")) @@ -108,10 +112,18 @@ void test_ksock_lsm(void) "LSM send bytes")) goto fail; - n = recvfrom(env.rfd, recv_data, sizeof(recv_data), 0, NULL, NULL); - if (ASSERT_EQ(n, sizeof(recv_data), "recvfrom len")) - ASSERT_MEMEQ(recv_data, skel->data->send_data, sizeof(recv_data), - "payload match"); + n = recvfrom(env.rfd, recv_data, sizeof(recv_data), MSG_TRUNC, + (struct sockaddr *)&src_addr, &src_addrlen); + if (!ASSERT_EQ(n, sizeof(recv_data), "recvfrom len")) + goto fail; + if (!ASSERT_EQ(ntohs(src_addr.sin_port), LOCAL_KSOCK_PORT, + "source address port")) + goto fail; + if (!ASSERT_EQ(ntohl(src_addr.sin_addr.s_addr), INADDR_LOOPBACK + 1, + "source address ip")) + goto fail; + ASSERT_MEMEQ(recv_data, skel->data->send_data, sizeof(recv_data), + "payload match"); fail: if (tfd >= 0) diff --git a/tools/testing/selftests/bpf/progs/ksock_common.h b/tools/testing/selftests/bpf/progs/ksock_common.h index 2a32cff2fbe9..87321f4ba4f5 100644 --- a/tools/testing/selftests/bpf/progs/ksock_common.h +++ b/tools/testing/selftests/bpf/progs/ksock_common.h @@ -11,6 +11,8 @@ struct bpf_ksock *bpf_ksock_create(const struct bpf_ksock_create_opts *opts, u32 opts__sz, int *err__uninit) __ksym; +int bpf_ksock_bind(struct bpf_ksock *ks, const union bpf_ksock_addr *addr, + u32 addr__sz) __ksym; int bpf_ksock_connect(struct bpf_ksock *ks, const union bpf_ksock_addr *addr, u32 addr__sz) __ksym; struct bpf_ksock *bpf_ksock_acquire(struct bpf_ksock *ks) __ksym; diff --git a/tools/testing/selftests/bpf/progs/ksock_lsm.c b/tools/testing/selftests/bpf/progs/ksock_lsm.c index 9808451098ef..28da777eea6c 100644 --- a/tools/testing/selftests/bpf/progs/ksock_lsm.c +++ b/tools/testing/selftests/bpf/progs/ksock_lsm.c @@ -10,6 +10,7 @@ char send_data[32] = "hello from bpf ksock"; +__u16 local_port; __be32 ipv4_remote; __u16 remote_port; int target_pid; @@ -32,19 +33,28 @@ int ksock_setup(void *ctx) return err; addr.sin.sin_family = AF_INET; + addr.sin.sin_port = bpf_htons(local_port); + addr.sin.sin_addr.s_addr = bpf_htonl(0x7f000002); /* 127.0.0.2 */ + + err = bpf_ksock_bind(ks, &addr, sizeof(addr)); + if (err) + goto err_release; + addr.sin.sin_port = bpf_htons(remote_port); addr.sin.sin_addr.s_addr = ipv4_remote; err = bpf_ksock_connect(ks, &addr, sizeof(addr)); - if (err) { - bpf_ksock_release(ks); - return err; - } + if (err) + goto err_release; err = ksock_ctx_insert(ks); if (err && err != -EEXIST) return err; return 0; + +err_release: + bpf_ksock_release(ks); + return err; } SEC("lsm.s/socket_bind") -- 2.43.0