From patchwork Wed Jan 8 08:38:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geliang Tang X-Patchwork-Id: 13930286 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 615221DFD85 for ; Wed, 8 Jan 2025 08:38:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736325505; cv=none; b=F+IWI8/Y7bB5VWwh5keUrSfYoA7VspLom7mFzI86bYdRVwS6I1F1nvDgOd1LIoHYW42n6yPIBvQL7m+huwFLFp6/muHoa+NUYBg1EqUSkmtajbuckrf1WpnR0i2/df3BrLMQfHPQa5Q0qjSybP3STQjNzvHKJuOUvwKd68YDFRU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736325505; c=relaxed/simple; bh=I9Kkgsrmf+ucCl5JyvivsiSKOw4HnJd3RKFG0KEVVrQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SCdESm9dEPLsVcjMg0A5v2ai1zVFP4ZWnHiboiAbYVD3G1WQ5IpOe+XnPI/ntqOh+XceYjLto6DX+Wbe0IgpTIvONFcOdd4e5+DEucPslm6LrSzXHxmxjwFdnW5kWB4iztrCpXvU1FK9vUrX8vYoxZHldGevMcpsK9xw3DlDSXk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gUE/Jahg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gUE/Jahg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 64A68C4CEE2; Wed, 8 Jan 2025 08:38:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1736325505; bh=I9Kkgsrmf+ucCl5JyvivsiSKOw4HnJd3RKFG0KEVVrQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gUE/JahgJIfh94yPUYdSVWr5mNCuSTSG2d0ObTRhRo4Ne0HazQX6JQvm61JCujmL6 4TJdUAHZI+3KxQvNr3Kdwha1rvk+4UedDA9nm3tjyHZQWKUoa/WrAsA6/O4vBtVZVH sl8jNuFMPr58TmlyG2iLklHOW2e4SK0NPWjdc2V8DpUpEzwTb0TGgN1ZI91toQTIWm iXMbVFCKdVp/BABNcdaKfKbwmpNyFXhYPQOFbVV7ld7ChGGAUek2xbf2SPQwL9yXI8 xww3qd1GXnaugoWb+ixSgV9QQNr+eJ1Tb4qR7lMyeaj4AmF9JLX4IUPMljGJT/SSVf 9rI8MBGXHMiAw== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Matthieu Baerts Subject: [PATCH mptcp-next v4 1/5] selftests/bpf: Add mptcp pm_nl_ctl link Date: Wed, 8 Jan 2025 16:38:08 +0800 Message-ID: <76a98d9ce8e1b2829dda64e22a2bb2c6ac7695a1.1736325184.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Geliang Tang This patch adds a symlink to MPTCP's pm_nl_ctl tool into bpf selftests, and updates Makefile to compile it. This is useful to run MPTCP BPF selftests on systems with an old version of IPRoute2. This tool can be used as an alternative to 'ip mptcp'. In addition, this tool is used as userspace path manager. "csf" and "dsf" commands of pm_nl_ctl for creating and destroying subflows, and "ann" and "rem" commands for signaling ADD_ADDR and RM_ADDR. These commands are not currently supported in 'ip mptcp' yet. MAINTAINERS needs to be updated since a new file is added in a non covered place. Signed-off-by: Geliang Tang Reviewed-by: Matthieu Baerts (NGI0) --- MAINTAINERS | 1 + tools/testing/selftests/bpf/Makefile | 4 +++- tools/testing/selftests/bpf/mptcp_pm_nl_ctl.c | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) create mode 120000 tools/testing/selftests/bpf/mptcp_pm_nl_ctl.c diff --git a/MAINTAINERS b/MAINTAINERS index a685c551faf0..3aae91daf9ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16480,6 +16480,7 @@ F: include/trace/events/mptcp.h F: include/uapi/linux/mptcp*.h F: net/mptcp/ F: tools/testing/selftests/bpf/*/*mptcp*.[ch] +F: tools/testing/selftests/bpf/*mptcp*.[ch] F: tools/testing/selftests/net/mptcp/ NETWORKING [TCP] diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 0a016cd71cba..a9a6dc1a806c 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -168,7 +168,8 @@ TEST_GEN_PROGS_EXTENDED = \ xdp_redirect_multi \ xdp_synproxy \ xdping \ - xskxceiver + xskxceiver \ + mptcp_pm_nl_ctl TEST_GEN_FILES += liburandom_read.so urandom_read sign-file uprobe_multi @@ -767,6 +768,7 @@ TRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read $(OUTPUT)/bpf_testmod.ko \ $(OUTPUT)/xdp_synproxy \ $(OUTPUT)/sign-file \ $(OUTPUT)/uprobe_multi \ + $(OUTPUT)/mptcp_pm_nl_ctl \ ima_setup.sh \ verify_sig_setup.sh \ $(wildcard progs/btf_dump_test_case_*.c) \ diff --git a/tools/testing/selftests/bpf/mptcp_pm_nl_ctl.c b/tools/testing/selftests/bpf/mptcp_pm_nl_ctl.c new file mode 120000 index 000000000000..5a08c255b278 --- /dev/null +++ b/tools/testing/selftests/bpf/mptcp_pm_nl_ctl.c @@ -0,0 +1 @@ +../net/mptcp/pm_nl_ctl.c \ No newline at end of file From patchwork Wed Jan 8 08:38:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geliang Tang X-Patchwork-Id: 13930287 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4914E1AB533 for ; Wed, 8 Jan 2025 08:38:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736325507; cv=none; b=WnmaG/mcWcgzA4CMJohZyWUtUOIRwWLrq3shTffh5GVq9uLzo/rNiF74WqVkwRWvczPdduK2LdpagjLRXnohYvPhrVegC2wcQb7Omns/wfSV+hV5/3B9RK3bmwUtUk1elnxgKe99Xu5k5Qcl0umw6HuGUm6gyQ7G/kfvffjGVZ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736325507; c=relaxed/simple; bh=/IpI9bjtVlyNNHO3Xl0lk1calaP06NTHNx+iQQg6dfg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d2LZzaP9LIljWbMUXnASGFKuSELi4OrIDdbwufREUgWKKPqqf8nuF4gf4Otej2DNCAzDwrG8ZfHdMDlU7rlkDyzGL1MJaVszjH1uKqwXmwNDITgChKG76YKEdpQYLOGUnHrcLNDup8ZSHjq8M+tdwtARqXjH2qtUvI2KN48Mw+Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ibu2NSbR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ibu2NSbR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BBEA8C4CEE0; Wed, 8 Jan 2025 08:38:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1736325506; bh=/IpI9bjtVlyNNHO3Xl0lk1calaP06NTHNx+iQQg6dfg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ibu2NSbRnBq+abCxN08owTLQWby5dtoIbLzkKoDlYqWa4r8oHdb/b4B/AvMG3gL7w hu00Z5w0mo0uQK0jisQme/j3/31hg79e/+RyYtkMQ09dK38twI/bGV4eVZH4oVoiyK iHzksV9YOiLo/JBgg2qmW9N6zner+Yd7YzySB0bbXt0qeMSaJc3ZoO3Mvs13ya6wt5 2odFsmyZqJRu4tKMK0sP1cv8IAd4jPeKeuCXR1DzIAkzeCUn4DRPflr3gQjNdBlbiP AwrJDai2JH+lmhR4vMeERQmpoIYpy/Vph0SJYdsTJv6fiPGDDdfqidu6zAIw1N2kre 1ce3b/d3AbIJw== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v4 2/5] selftests/bpf: Use pm_nl_ctl if ip mptcp not supported Date: Wed, 8 Jan 2025 16:38:09 +0800 Message-ID: <7d3e8bd4357857f862ceb3af29a866423c00425b.1736325184.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Geliang Tang If running MPTCP BPF selftests on systems with an old version of IPRoute2, 'ip mptcp' command is not supported. In this case, instead of skipping the test, falling back to using 'pm_nl_ctl' tool is a better option. This patch adds an 'ip_mptcp' argument for endpoint_add() to control whether to use 'ip mptcp' or 'pm_nl_ctl' to add an endpoint. Signed-off-by: Geliang Tang --- .../testing/selftests/bpf/prog_tests/mptcp.c | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c index 1d68bbda3370..5cab0aa8fb27 100644 --- a/tools/testing/selftests/bpf/prog_tests/mptcp.c +++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c @@ -28,6 +28,7 @@ #define ADDR6_3 "dead:beef:3::1" #define ADDR6_4 "dead:beef:4::1" #define PORT_1 10001 +#define PM_CTL "./mptcp_pm_nl_ctl" #define WITH_DATA true #define WITHOUT_DATA false @@ -366,13 +367,18 @@ static int address_init(void) return -1; } -static int endpoint_add(char *addr, char *flags) +static int endpoint_add(char *addr, char *flags, bool ip_mptcp) { - return SYS_NOFAIL("ip -net %s mptcp endpoint add %s %s", NS_TEST, addr, flags); + if (ip_mptcp) + return SYS_NOFAIL("ip -net %s mptcp endpoint add %s %s", + NS_TEST, addr, flags); + return SYS_NOFAIL("ip netns exec %s %s add %s flags %s", + NS_TEST, PM_CTL, addr, flags); } static int endpoint_init(char *flags, u8 endpoints) { + bool ip_mptcp = true; int ret = -1; if (!endpoints || endpoints > 4) @@ -383,17 +389,16 @@ static int endpoint_init(char *flags, u8 endpoints) if (SYS_NOFAIL("ip -net %s mptcp limits set add_addr_accepted 4 subflows 4", NS_TEST)) { - printf("'ip mptcp' not supported, skip this test.\n"); - test__skip(); - goto fail; + SYS(fail, "ip netns exec %s %s limits 4 4", NS_TEST, PM_CTL); + ip_mptcp = false; } if (endpoints > 1) - ret = endpoint_add(ADDR_2, flags); + ret = endpoint_add(ADDR_2, flags, ip_mptcp); if (endpoints > 2) - ret = ret ?: endpoint_add(ADDR_3, flags); + ret = ret ?: endpoint_add(ADDR_3, flags, ip_mptcp); if (endpoints > 3) - ret = ret ?: endpoint_add(ADDR_4, flags); + ret = ret ?: endpoint_add(ADDR_4, flags, ip_mptcp); fail: return ret; From patchwork Wed Jan 8 08:38:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geliang Tang X-Patchwork-Id: 13930288 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F2621A76BC for ; Wed, 8 Jan 2025 08:38:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736325509; cv=none; b=ANA38TLhZZJU08m+MOVRHLo/534p009sVMdfVTbQm6+653WDCfCJiKuEMayrk4oRSJ+Bh46m3I49SCPdspui7vG7sc89zW65dLEDX1WFOzmuSIHFd0GQ2GoD9bZWsMjtEhLuAzmgf9YU77dgIaQOgAsTzjqwPbqKzYqSC+Sew4g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736325509; c=relaxed/simple; bh=ToG1MF7uW2QUuMDYIFMQfrYfVuMV41rdERJmIk7VGKQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o72qx0TNEX9VZQnYD0Idq3EkW6P9sXtMcin0vbZpgEYi7Knq5MkJq/dx8t/KAjLz4DQv/o63M1f8lNTn/gPe0stxIlvhJPpv8imbB9X0FgLE//bDJ9u+WO6/Qe+o0Ls4Sza4SnbdFwk6LyW3B7RsiI/wokRdW5zeO7cyzIOjbso= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dHCB9fgv; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dHCB9fgv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6309CC4CEE1; Wed, 8 Jan 2025 08:38:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1736325508; bh=ToG1MF7uW2QUuMDYIFMQfrYfVuMV41rdERJmIk7VGKQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dHCB9fgvdvDFLXhJ+4vxhQdM+Z+At9VG2OYH34roVdGqqxYPgwJ8YqYEfhNvqe2RP r4SmS6ugedSLhPC3h72jpYZwIeRTe227zreWl5v/UR1+KOGsAP/OoPOfNPq2v32iJe WeLIIzZB2EVgwKGyZ+/TefhXSlVTH1/Ia6DJtA4iSDSW/S7rsT8AuEI1CgNtEPXb04 9wtb2PXfGAYvlO/fNTmuwV6M791phv2szPJ25/d1F5UXkCAhA3a6nx/PbCZ69EHB+f 8RH6So+oQ1rbG5qMDSI5mjBg40+0sMEQE6cQED6mY9HZZkjTMwO6g6yx6yjxkF+DVz gMfOppSjJbT4Q== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v4 3/5] bpf: Add mptcp_userspace_pm_addr bpf_iter Date: Wed, 8 Jan 2025 16:38:10 +0800 Message-ID: <10551d58b505f20754a13302ce2340e220a3e7a5.1736325184.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Geliang Tang Just like the mptcp_subflow bpf_iter used to implement the MPTCP BPF packet scheduler, another bpf_iter is also needed, named mptcp_userspace_pm_addr, to traverse all address entries on userspace_pm_local_addr_list of an MPTCP socket for implementing the MPTCP BPF path manager. In kernel space, we walk this list like this: mptcp_for_each_userspace_pm_addr(msk, entry) kfunc(entry); With the mptcp_userspace_pm_addr bpf_iter, bpf_for_each() can be used to do the same thing in BPF program: bpf_for_each(mptcp_userspace_pm_addr, entry, msk) kfunc(entry); This bpf_iter should be invoked under holding the msk pm lock, so use lockdep_assert_held() to assert the lock is holding. Signed-off-by: Geliang Tang --- net/mptcp/bpf.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c index 923895322b2c..c7f5d208f6cc 100644 --- a/net/mptcp/bpf.c +++ b/net/mptcp/bpf.c @@ -220,6 +220,15 @@ struct bpf_iter_mptcp_subflow_kern { struct list_head *pos; } __aligned(8); +struct bpf_iter_mptcp_userspace_pm_addr { + __u64 __opaque[2]; +} __aligned(8); + +struct bpf_iter_mptcp_userspace_pm_addr_kern { + struct mptcp_sock *msk; + struct list_head *pos; +} __aligned(8); + __bpf_kfunc_start_defs(); __bpf_kfunc static struct mptcp_subflow_context * @@ -273,6 +282,46 @@ bpf_iter_mptcp_subflow_destroy(struct bpf_iter_mptcp_subflow *it) { } +__bpf_kfunc static int +bpf_iter_mptcp_userspace_pm_addr_new(struct bpf_iter_mptcp_userspace_pm_addr *it, + struct mptcp_sock *msk) +{ + struct bpf_iter_mptcp_userspace_pm_addr_kern *kit = (void *)it; + + BUILD_BUG_ON(sizeof(struct bpf_iter_mptcp_userspace_pm_addr_kern) > + sizeof(struct bpf_iter_mptcp_userspace_pm_addr)); + BUILD_BUG_ON(__alignof__(struct bpf_iter_mptcp_userspace_pm_addr_kern) != + __alignof__(struct bpf_iter_mptcp_userspace_pm_addr)); + + kit->msk = msk; + if (!msk) + return -EINVAL; + + if (!spin_is_locked(&msk->pm.lock)) + return -EINVAL; + + kit->pos = &msk->pm.userspace_pm_local_addr_list; + return 0; +} + +__bpf_kfunc static struct mptcp_pm_addr_entry * +bpf_iter_mptcp_userspace_pm_addr_next(struct bpf_iter_mptcp_userspace_pm_addr *it) +{ + struct bpf_iter_mptcp_userspace_pm_addr_kern *kit = (void *)it; + + if (!kit->msk || list_is_last(kit->pos, + &kit->msk->pm.userspace_pm_local_addr_list)) + return NULL; + + kit->pos = kit->pos->next; + return list_entry(kit->pos, struct mptcp_pm_addr_entry, list); +} + +__bpf_kfunc static void +bpf_iter_mptcp_userspace_pm_addr_destroy(struct bpf_iter_mptcp_userspace_pm_addr *it) +{ +} + __bpf_kfunc static struct mptcp_sock *bpf_mptcp_sock_acquire(struct mptcp_sock *msk) { @@ -310,6 +359,9 @@ BTF_ID_FLAGS(func, bpf_mptcp_subflow_ctx, KF_RET_NULL) BTF_ID_FLAGS(func, bpf_iter_mptcp_subflow_new, KF_ITER_NEW | KF_TRUSTED_ARGS) BTF_ID_FLAGS(func, bpf_iter_mptcp_subflow_next, KF_ITER_NEXT | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_iter_mptcp_subflow_destroy, KF_ITER_DESTROY) +BTF_ID_FLAGS(func, bpf_iter_mptcp_userspace_pm_addr_new, KF_ITER_NEW | KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_iter_mptcp_userspace_pm_addr_next, KF_ITER_NEXT | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_iter_mptcp_userspace_pm_addr_destroy, KF_ITER_DESTROY) BTF_ID_FLAGS(func, bpf_mptcp_sock_acquire, KF_ACQUIRE | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_mptcp_sock_release, KF_RELEASE) BTF_KFUNCS_END(bpf_mptcp_common_kfunc_ids) From patchwork Wed Jan 8 08:38:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geliang Tang X-Patchwork-Id: 13930289 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 90F9A1DFD85 for ; Wed, 8 Jan 2025 08:38:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736325510; cv=none; b=AFGWbTfm8Ml5qAhbW4cfA5PlOsfXJvuIXqIkcF9BgxHag323IIBa/67Kl5FwxexHRvW9KkwAZ9j6ebOZa4hOWr0Q9seS+GCCqvqqGGUnoAtrtyR17/d7b5QAkJ5Zt6RQTyOrScksMHwT0mXils7EtiKnw1jgYdFNg0vhQysNWK0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736325510; c=relaxed/simple; bh=WAiDKh6AeQkNjXVZ7a6GfC+r0kn5c58+ZE4rhLbaLbU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FQ2rFKJ/9pSQTMwXTch8NZzewHm6xp98say0R2Fnoo0BK0P4my/qGkHpgT4nYwbhWGxcTMFJ+x7L8buEzB7Bbwq2fs3dSpUtjTV0rshSDTq3YuVvwwUzmlMceWzSEvdeTO0Zw8m9h/Qs08iVYVSTCjAr1e0q9m1tB6hq0/lWErk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bUTbPloE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bUTbPloE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3D3D5C4CEE0; Wed, 8 Jan 2025 08:38:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1736325510; bh=WAiDKh6AeQkNjXVZ7a6GfC+r0kn5c58+ZE4rhLbaLbU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bUTbPloEnAw038QTJ7uPPsJWMjJTuXr9W4slPJ629StIZLKJQ5KU36cfAcmj9MYBN 7qHZhhzLuhyIhlz9y7g1FCMd9alolPht8Er+nuJ+ls6xW0hS/YGhLWAp3WJHICIeX0 F3ZywirO9ZzmDKv1V8+npAuDYxc2tRUMQdnwXtV/RzzpYp3LESCuUoh8Sn9mO/TaHh /3xDRfvFliNflVM5BfyfzOIqK28HkUdwmCkydDYtJiL9pjhc4m6oTZXH3JhFjouRY1 HU97c+qw+zorZHGOWDjmOq/TwXnHck6YtY6ScvqTGt4gNjVbrPk3tgOHuCx7P8wQG3 K1WNawLNC395A== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v4 4/5] bpf: Export more helpers for mptcp_userspace_pm_addr test Date: Wed, 8 Jan 2025 16:38:11 +0800 Message-ID: <3e9fbc5a0f28024f130b2d67c6ee38b09e134a7f.1736325184.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Geliang Tang The mptcp_userspace_pm_addr bpf_iter should be invoked under holding the msk pm lock, so spin_lock_bh() and spin_unlock_bh() are needed in BPF program to hold or release the msk pm lock. And bpf_ipv4_is_private_10() helper is also needed by the mptcp_userspace_pm_addr bpf_iter selftest program. This patch adds the corresponding BPF wrappers for these helpers and adds them to the mptcp common kfunc_set. Signed-off-by: Geliang Tang --- net/mptcp/bpf.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c index c7f5d208f6cc..5e748cebb787 100644 --- a/net/mptcp/bpf.c +++ b/net/mptcp/bpf.c @@ -339,6 +339,21 @@ __bpf_kfunc static void bpf_mptcp_sock_release(struct mptcp_sock *msk) WARN_ON_ONCE(!sk || !refcount_dec_not_one(&sk->sk_refcnt)); } +__bpf_kfunc static void bpf_spin_lock_bh(spinlock_t *lock) +{ + spin_lock_bh(lock); +} + +__bpf_kfunc static void bpf_spin_unlock_bh(spinlock_t *lock) +{ + spin_unlock_bh(lock); +} + +__bpf_kfunc static bool bpf_ipv4_is_private_10(__be32 addr) +{ + return ipv4_is_private_10(addr); +} + __bpf_kfunc struct mptcp_subflow_context * bpf_mptcp_subflow_ctx_by_pos(const struct mptcp_sched_data *data, unsigned int pos) { @@ -364,6 +379,9 @@ BTF_ID_FLAGS(func, bpf_iter_mptcp_userspace_pm_addr_next, KF_ITER_NEXT | KF_RET_ BTF_ID_FLAGS(func, bpf_iter_mptcp_userspace_pm_addr_destroy, KF_ITER_DESTROY) BTF_ID_FLAGS(func, bpf_mptcp_sock_acquire, KF_ACQUIRE | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_mptcp_sock_release, KF_RELEASE) +BTF_ID_FLAGS(func, bpf_spin_lock_bh) +BTF_ID_FLAGS(func, bpf_spin_unlock_bh) +BTF_ID_FLAGS(func, bpf_ipv4_is_private_10) BTF_KFUNCS_END(bpf_mptcp_common_kfunc_ids) static const struct btf_kfunc_id_set bpf_mptcp_common_kfunc_set = { From patchwork Wed Jan 8 08:38:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geliang Tang X-Patchwork-Id: 13930290 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 946851A76BC for ; Wed, 8 Jan 2025 08:38:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736325512; cv=none; b=s+TcqfKU3H+v2o3O1M2O7hqSJr4Ie9XPuDbiVcBAomXvTPBJHlX9WCdR4o8k6HsFbEQ89C++Fyfy41mCsbD4YGHe8B4cwfcahIpPcZ6ONDju8s5QTsawObswfjm2iFUIEt6bXO3oEv+ht5SI+zA1h7WKHoicIR20/daRRUF6BA0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736325512; c=relaxed/simple; bh=YVd9gXGs01Re+5GaaTIJ/JPWeTiRCcmF+G2PXqg+0U8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K8oYyDHc4lQQ05GtS+ExNvqkd759YNouGONBXL5g6vszkICGL4XK+Ju1qjtFM3yCzPc6kUzR9tomWSX4WJ6Tc37UUb5DBa8qvTuHJQvrsivsvt9UgdXozVjN7xCSWkkfrFH3zDxdBKed7U9ClnGum5UV630MvUSmyBLh182jUcA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JPMCtRZr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JPMCtRZr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 163D9C4CEE1; Wed, 8 Jan 2025 08:38:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1736325512; bh=YVd9gXGs01Re+5GaaTIJ/JPWeTiRCcmF+G2PXqg+0U8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JPMCtRZrUKeUEOkZC/iBlTucCqBWGgBP4DsRbiGH7dmPqzK5kkRwKZLIfmwc4wxRj xUB40wVXSLdexAdlpBZq9RPuJYX/qxPIJuZqVj10wTQ3+mj0oOso9CQiOA9G3bsXuD y2FxisqpZAg7GWWa1L2aU4znmSoTvy6OiZ/9g7fs8DMRobu5tJmeCaEwqTWAeNJVJ9 OPE1cyqTKA2o4oJxTW9pcvw6xDyUPAQrKWa5LJFAlEv8lP1j/BaiE7CUw3ey5OE5J+ oGsix4lBea+810kNKCOhqGcaoh/Arqw+Dt6rASKsc5yn4ILcj4olSh6e3iMQyp1aMc xS6SnjRlDhlOg== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang Subject: [PATCH mptcp-next v4 5/5] selftests/bpf: Add mptcp_userspace_pm_addr bpf_iter subtest Date: Wed, 8 Jan 2025 16:38:12 +0800 Message-ID: <37907405c495249ead2cb2f1a6c505d9062710f7.1736325184.git.tanggeliang@kylinos.cn> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Geliang Tang This patch adds a test program for the newly added mptcp_userspace_pm_addr bpf_iter in SEC "cgroup/getsockopt". This test iterates over all address entries on the local address list of userspace PM and check whether each one is an IPv4mapped address. Export mptcp_userspace_pm_addr helpers _new/_next/_destroy into bpf_experimental.h. Use bpf_mptcp_sock_acquire() to acquire the msk, then lock the msk pm lock and use bpf_for_each(mptcp_userspace_pm_addr) to walk the local address list of this msk. Invoke bpf_ipv4_is_private_10() in the loop to check whether the address is a "10.*" one. Then Add the address ID of each entry to local veriable local_ids. Out of the loop, unlock the msk pm lock and use bpf_mptcp_sock_release() to release the msk. Finally, assign local_ids to global variable ids so that the application can obtain this value. Also enable CONFIG_MPTCP_IPV6 in bpf config. Add a subtest named test_iters_address to load and verify the newly added mptcp_userspace_pm_addr type bpf_iter example in test_mptcp. Since mptcp_userspace_pm_addr bpf_iter iterates over all address entries on the local address list of userspace PM. A set of userspace PM helpers are added. Set pm_type and start "pm_nl_ctl events" command to save pm events into the log file /tmp/bpf_userspace_pm_events in userspace_pm_init(). Kill "pm_nl_ctl" command and remove the log file in userspace_pm_cleanup(). Parse the log file in userspace_pm_add_subflow() to get the token, sport and dport values, then use "pm_nl_ctl csf" command to create a subflow. Use the helper userspace_pm_add_subflow() to add 3 new subflow endpoints. Send a byte of message to start the mptcp connection, and receive the message. getsockopt() is invoked to trigger the "cgroup/getsockopt" test program. Check if skel->bss->ids equals 60 to verify whether the program loops three times as expected. Signed-off-by: Geliang Tang --- .../testing/selftests/bpf/bpf_experimental.h | 8 + .../testing/selftests/bpf/prog_tests/mptcp.c | 214 ++++++++++++++++++ tools/testing/selftests/bpf/progs/mptcp_bpf.h | 5 + .../selftests/bpf/progs/mptcp_bpf_iters.c | 38 ++++ 4 files changed, 265 insertions(+) diff --git a/tools/testing/selftests/bpf/bpf_experimental.h b/tools/testing/selftests/bpf/bpf_experimental.h index 2ab3f0063c0f..01201917a446 100644 --- a/tools/testing/selftests/bpf/bpf_experimental.h +++ b/tools/testing/selftests/bpf/bpf_experimental.h @@ -583,6 +583,14 @@ 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; +struct bpf_iter_mptcp_userspace_pm_addr; +extern int bpf_iter_mptcp_userspace_pm_addr_new(struct bpf_iter_mptcp_userspace_pm_addr *it, + struct mptcp_sock *msk) __weak __ksym; +extern struct mptcp_pm_addr_entry * +bpf_iter_mptcp_userspace_pm_addr_next(struct bpf_iter_mptcp_userspace_pm_addr *it) __weak __ksym; +extern void +bpf_iter_mptcp_userspace_pm_addr_destroy(struct bpf_iter_mptcp_userspace_pm_addr *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/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c index 5cab0aa8fb27..d50dc332f545 100644 --- a/tools/testing/selftests/bpf/prog_tests/mptcp.c +++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c @@ -29,6 +29,7 @@ #define ADDR6_4 "dead:beef:4::1" #define PORT_1 10001 #define PM_CTL "./mptcp_pm_nl_ctl" +#define PM_EVENTS "/tmp/bpf_userspace_pm_events" #define WITH_DATA true #define WITHOUT_DATA false @@ -57,6 +58,14 @@ #endif #define MPTCP_SCHED_NAME_MAX 16 +enum mptcp_pm_type { + MPTCP_PM_TYPE_KERNEL = 0, + MPTCP_PM_TYPE_USERSPACE, + + __MPTCP_PM_TYPE_NR, + __MPTCP_PM_TYPE_MAX = __MPTCP_PM_TYPE_NR - 1, +}; + static const unsigned int total_bytes = 10 * 1024 * 1024; static int duration; @@ -252,6 +261,19 @@ static void send_byte(int fd) ASSERT_EQ(write(fd, &b, sizeof(b)), 1, "send single byte"); } +static int recv_byte(int fd) +{ + char buf[1]; + ssize_t n; + + n = recv(fd, buf, sizeof(buf), 0); + if (CHECK(n <= 0, "recv_byte", "recv")) { + log_err("failed/partial recv"); + return -1; + } + return 0; +} + static int verify_mptcpify(int server_fd, int client_fd) { struct __mptcp_info info; @@ -567,6 +589,196 @@ static void test_iters_subflow(void) close(cgroup_fd); } +static int userspace_pm_init(enum mptcp_pm_type pm_type) +{ + if (address_init()) + goto fail; + + SYS(fail, "ip netns exec %s sysctl -qw net.mptcp.pm_type=%u", + NS_TEST, pm_type); + SYS(fail, "ip netns exec %s %s limits 4 4", + NS_TEST, PM_CTL); + SYS(fail, "ip netns exec %s %s events >> %s 2>&1 &", + NS_TEST, PM_CTL, PM_EVENTS); + + return 0; +fail: + return -1; +} + +static void userspace_pm_cleanup(void) +{ + SYS_NOFAIL("ip netns exec %s killall %s > /dev/null 2>&1", + NS_TEST, PM_CTL); + SYS_NOFAIL("ip netns exec %s rm -rf %s", NS_TEST, PM_EVENTS); +} + +static int userspace_pm_get_events_line(char *type, char *line) +{ + char buf[BUFSIZ], *str; + size_t len; + int fd; + + fd = open(PM_EVENTS, O_RDONLY); + if (fd < 0) { + log_err("failed to open pm events\n"); + return -1; + } + + len = read(fd, buf, sizeof(buf)); + close(fd); + if (len <= 0) { + log_err("failed to read pm events\n"); + return -1; + } + + str = strstr(buf, type); + if (!str) { + log_err("failed to get type %s pm event\n", type); + return -1; + } + + strcpy(line, str); + return 0; +} + +static int userspace_pm_get_token(int fd) +{ + char line[1024], *str; + __u32 token; + int i; + + /* Wait max 2 sec for the connection to be established */ + for (i = 0; i < 10; i++) { + usleep(200000); /* 0.2s */ + send_byte(fd); + + sync(); + if (userspace_pm_get_events_line("type:2", line)) + continue; + str = strstr(line, "token"); + if (!str) + continue; + if (sscanf(str, "token:%u,", &token) != 1) + continue; + return token; + } + + return 0; +} + +static int userspace_pm_add_subflow(__u32 token, char *addr, __u8 id) +{ + bool ipv6 = strstr(addr, ":"); + char line[1024], *str; + __u32 sport, dport; + + if (userspace_pm_get_events_line("type:2", line)) + return -1; + + str = strstr(line, "sport"); + if (!str || sscanf(str, "sport:%u,dport:%u,", &sport, &dport) != 2) { + log_err("add_subflow error, str=%s\n", str); + return -1; + } + + str = ipv6 ? (strstr(addr, ".") ? "::ffff:"ADDR_1 : ADDR6_1) : ADDR_1; + SYS_NOFAIL("ip netns exec %s %s csf lip %s lid %u rip %s rport %u token %u", + NS_TEST, PM_CTL, addr, id, str, dport, token); + + return 0; +} + +static void run_iters_address(void) +{ + int server_fd, client_fd, accept_fd; + int is_mptcp, err; + socklen_t len; + __u32 token; + + server_fd = start_mptcp_server(AF_INET, ADDR_1, PORT_1, 0); + if (!ASSERT_OK_FD(server_fd, "start_mptcp_server")) + return; + + client_fd = connect_to_fd(server_fd, 0); + if (!ASSERT_OK_FD(client_fd, "connect_to_fd")) + goto close_server; + + accept_fd = accept(server_fd, NULL, NULL); + if (!ASSERT_OK_FD(accept_fd, "accept")) + goto close_client; + + token = userspace_pm_get_token(client_fd); + if (!token) + goto close_client; + recv_byte(accept_fd); + usleep(200000); /* 0.2s */ + + err = userspace_pm_add_subflow(token, ADDR_2, 10); + err = err ?: userspace_pm_add_subflow(token, ADDR_3, 20); + err = err ?: userspace_pm_add_subflow(token, ADDR_4, 30); + if (!ASSERT_OK(err, "userspace_pm_add_subflow")) + goto close_accept; + + send_byte(accept_fd); + recv_byte(client_fd); + + len = sizeof(is_mptcp); + /* mainly to trigger the BPF program */ + err = getsockopt(client_fd, SOL_TCP, TCP_IS_MPTCP, &is_mptcp, &len); + if (ASSERT_OK(err, "getsockopt(client_fd, TCP_IS_MPTCP)")) + ASSERT_EQ(is_mptcp, 1, "is_mptcp"); + +close_accept: + close(accept_fd); +close_client: + close(client_fd); +close_server: + close(server_fd); +} + +static void test_iters_address(void) +{ + struct mptcp_bpf_iters *skel; + struct netns_obj *netns; + int cgroup_fd; + int err; + + cgroup_fd = test__join_cgroup("/iters_address"); + if (!ASSERT_OK_FD(cgroup_fd, "join_cgroup: iters_address")) + return; + + skel = mptcp_bpf_iters__open_and_load(); + if (!ASSERT_OK_PTR(skel, "skel_open_load: iters_address")) + goto close_cgroup; + + skel->links.iters_address = bpf_program__attach_cgroup(skel->progs.iters_address, + cgroup_fd); + if (!ASSERT_OK_PTR(skel->links.iters_address, "attach getsockopt")) + goto skel_destroy; + + netns = netns_new(NS_TEST, true); + if (!ASSERT_OK_PTR(netns, "netns_new")) + goto skel_destroy; + + err = userspace_pm_init(MPTCP_PM_TYPE_USERSPACE); + if (!ASSERT_OK(err, "userspace_pm_init: iters_address")) + goto close_netns; + + run_iters_address(); + + /* 10 + 20 + 30 = 60 */ + ASSERT_EQ(skel->bss->ids, 60, "address ids"); + + userspace_pm_cleanup(); +close_netns: + netns_free(netns); +skel_destroy: + mptcp_bpf_iters__destroy(skel); +close_cgroup: + close(cgroup_fd); +} + static struct netns_obj *sched_init(char *flags, char *sched) { struct netns_obj *netns; @@ -750,6 +962,8 @@ void test_mptcp(void) test_subflow(); if (test__start_subtest("iters_subflow")) test_iters_subflow(); + if (test__start_subtest("iters_address")) + test_iters_address(); if (test__start_subtest("default")) test_default(); if (test__start_subtest("first")) diff --git a/tools/testing/selftests/bpf/progs/mptcp_bpf.h b/tools/testing/selftests/bpf/progs/mptcp_bpf.h index b1f6e1fb467e..5e29ac93d823 100644 --- a/tools/testing/selftests/bpf/progs/mptcp_bpf.h +++ b/tools/testing/selftests/bpf/progs/mptcp_bpf.h @@ -51,6 +51,11 @@ bpf_mptcp_subflow_ctx(const struct sock *sk) __ksym; extern struct sock * bpf_mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow) __ksym; +extern void bpf_spin_lock_bh(spinlock_t *lock) __ksym; +extern void bpf_spin_unlock_bh(spinlock_t *lock) __ksym; + +extern bool bpf_ipv4_is_private_10(__be32 addr) __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_iters.c b/tools/testing/selftests/bpf/progs/mptcp_bpf_iters.c index fd5691a4073b..e11339641e8d 100644 --- a/tools/testing/selftests/bpf/progs/mptcp_bpf_iters.c +++ b/tools/testing/selftests/bpf/progs/mptcp_bpf_iters.c @@ -61,3 +61,41 @@ int iters_subflow(struct bpf_sockopt *ctx) bpf_mptcp_sock_release(msk); return 1; } + +SEC("cgroup/getsockopt") +int iters_address(struct bpf_sockopt *ctx) +{ + struct mptcp_pm_addr_entry *entry; + struct bpf_sock *sk = ctx->sk; + struct mptcp_sock *msk; + int local_ids = 0; + + if (ctx->level != SOL_TCP || ctx->optname != TCP_IS_MPTCP) + return 1; + + msk = bpf_skc_to_mptcp_sock(sk); + if (!msk || msk->pm.server_side) + return 1; + + msk = bpf_mptcp_sock_acquire(msk); + if (!msk) + return 1; + bpf_spin_lock_bh(&msk->pm.lock); + bpf_for_each(mptcp_userspace_pm_addr, entry, msk) { + /* Here MPTCP-specific path manager kfunc can be called: + * this test is not doing anything really useful, only to + * verify the iteration works. + */ + + if (!bpf_ipv4_is_private_10(entry->addr.addr.s_addr)) + break; + + local_ids += entry->addr.id; + } + bpf_spin_unlock_bh(&msk->pm.lock); + bpf_mptcp_sock_release(msk); + + ids = local_ids; + + return 1; +}