diff mbox series

[mptcp-next,v6,04/10] selftests/bpf: Add mptcp_subflow bpf_iter test prog

Message ID 6b52ba4a67304ccb3b36f9e098a8e26d9ffb58ff.1727168628.git.tanggeliang@kylinos.cn (mailing list archive)
State Superseded, archived
Headers show
Series add mptcp_subflow bpf_iter | expand

Checks

Context Check Description
matttbe/checkpatch warning total: 0 errors, 1 warnings, 6 checks, 71 lines checked
matttbe/shellcheck success MPTCP selftests files have not been modified
matttbe/build success Build and static analysis OK
matttbe/KVM_Validation__normal success Success! ✅
matttbe/KVM_Validation__debug success Success! ✅
matttbe/KVM_Validation__btf__only_bpftest_all_ success Success! ✅

Commit Message

Geliang Tang Sept. 24, 2024, 9:09 a.m. UTC
From: Geliang Tang <tanggeliang@kylinos.cn>

This patch adds a new mptcp bpf selftest program in "cgroup/getsockopt"
for the newly added mptcp_subflow bpf_iter.

Export bpf_mptcp_sk, bpf_iter_mptcp_subflow_new/_next/_destroy and
bpf_mptcp_sock_acquire/_release into bpf_experimental.h, then use
bpf_for_each(mptcp_subflow, subflow, msk) to walk the mptcp subflow list.
Invoke kfuncs mptcp_subflow_active() and mptcp_subflow_set_scheduled() in
bpf_for_each loop.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 .../testing/selftests/bpf/bpf_experimental.h  |  7 +++
 tools/testing/selftests/bpf/progs/mptcp_bpf.h |  6 +++
 .../selftests/bpf/progs/mptcp_bpf_iter.c      | 46 +++++++++++++++++++
 3 files changed, 59 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/progs/mptcp_bpf_iter.c
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/bpf_experimental.h b/tools/testing/selftests/bpf/bpf_experimental.h
index 828556cdc2f0..97aad95c90c6 100644
--- a/tools/testing/selftests/bpf/bpf_experimental.h
+++ b/tools/testing/selftests/bpf/bpf_experimental.h
@@ -549,6 +549,13 @@  extern int bpf_iter_css_new(struct bpf_iter_css *it,
 extern struct cgroup_subsys_state *bpf_iter_css_next(struct bpf_iter_css *it) __weak __ksym;
 extern void bpf_iter_css_destroy(struct bpf_iter_css *it) __weak __ksym;
 
+struct bpf_iter_mptcp_subflow;
+extern int bpf_iter_mptcp_subflow_new(struct bpf_iter_mptcp_subflow *it,
+				      struct mptcp_sock *msk) __weak __ksym;
+extern struct mptcp_subflow_context *
+bpf_iter_mptcp_subflow_next(struct bpf_iter_mptcp_subflow *it) __weak __ksym;
+extern void bpf_iter_mptcp_subflow_destroy(struct bpf_iter_mptcp_subflow *it) __weak __ksym;
+
 extern int bpf_wq_init(struct bpf_wq *wq, void *p__map, unsigned int flags) __weak __ksym;
 extern int bpf_wq_start(struct bpf_wq *wq, unsigned int flags) __weak __ksym;
 extern int bpf_wq_set_callback_impl(struct bpf_wq *wq,
diff --git a/tools/testing/selftests/bpf/progs/mptcp_bpf.h b/tools/testing/selftests/bpf/progs/mptcp_bpf.h
index c3800f986ae1..ab46b66422c4 100644
--- a/tools/testing/selftests/bpf/progs/mptcp_bpf.h
+++ b/tools/testing/selftests/bpf/progs/mptcp_bpf.h
@@ -43,6 +43,12 @@  mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow)
 }
 
 /* ksym */
+extern bool mptcp_subflow_active(struct mptcp_subflow_context *subflow) __ksym;
+extern struct mptcp_sock *bpf_mptcp_sk(struct sock *sk) __ksym;
+
+extern struct mptcp_sock *bpf_mptcp_sock_acquire(struct mptcp_sock *msk) __ksym;
+extern void bpf_mptcp_sock_release(struct mptcp_sock *msk) __ksym;
+
 extern void mptcp_subflow_set_scheduled(struct mptcp_subflow_context *subflow,
 					bool scheduled) __ksym;
 
diff --git a/tools/testing/selftests/bpf/progs/mptcp_bpf_iter.c b/tools/testing/selftests/bpf/progs/mptcp_bpf_iter.c
new file mode 100644
index 000000000000..39240df5bc3c
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/mptcp_bpf_iter.c
@@ -0,0 +1,46 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2024, Kylin Software */
+
+/* vmlinux.h, bpf_helpers.h and other 'define' */
+#include "bpf_tracing_net.h"
+#include "mptcp_bpf.h"
+
+char _license[] SEC("license") = "GPL";
+int subflows;
+int pid;
+
+SEC("cgroup/getsockopt")
+int mptcp_getsockopt(struct bpf_sockopt *ctx)
+{
+	struct mptcp_subflow_context *subflow;
+	struct bpf_sock *sk = ctx->sk;
+	struct mptcp_sock *msk;
+
+	if (bpf_get_current_pid_tgid() >> 32 != pid)
+		return 1;
+
+	if (!sk || sk->protocol != IPPROTO_MPTCP ||
+	    ctx->level != SOL_TCP || ctx->optname != TCP_CONGESTION)
+		return 1;
+
+	msk = bpf_mptcp_sock_acquire(bpf_mptcp_sk((struct sock *)sk));
+	if (!msk)
+		return 1;
+
+	subflows = 0;
+
+	bpf_for_each(mptcp_subflow, subflow, msk) {
+		if (subflow->token != msk->token) {
+			ctx->retval = -1;
+			break;
+		}
+
+		if (!mptcp_subflow_active(subflow))
+			continue;
+
+		subflows++;
+	}
+	bpf_mptcp_sock_release(msk);
+
+	return 1;
+}