netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next v14 0/4] bpf: Force to MPTCP
@ 2023-08-16  1:11 Geliang Tang
  2023-08-16  1:11 ` [PATCH bpf-next v14 1/4] bpf: Add update_socket_protocol hook Geliang Tang
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Geliang Tang @ 2023-08-16  1:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, Florent Revest,
	Brendan Jackman, Matthieu Baerts, Mat Martineau, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, John Johansen,
	Paul Moore, James Morris, Serge E. Hallyn, Stephen Smalley,
	Eric Paris, Mykola Lysenko, Shuah Khan, Simon Horman
  Cc: Geliang Tang, bpf, netdev, mptcp, linux-security-module, selinux,
	linux-kselftest

As is described in the "How to use MPTCP?" section in MPTCP wiki [1]:

"Your app should create sockets with IPPROTO_MPTCP as the proto:
( socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); ). Legacy apps can be
forced to create and use MPTCP sockets instead of TCP ones via the
mptcpize command bundled with the mptcpd daemon."

But the mptcpize (LD_PRELOAD technique) command has some limitations
[2]:

 - it doesn't work if the application is not using libc (e.g. GoLang
apps)
 - in some envs, it might not be easy to set env vars / change the way
apps are launched, e.g. on Android
 - mptcpize needs to be launched with all apps that want MPTCP: we could
have more control from BPF to enable MPTCP only for some apps or all the
ones of a netns or a cgroup, etc.
 - it is not in BPF, we cannot talk about it at netdev conf.

So this patchset attempts to use BPF to implement functions similer to
mptcpize.

The main idea is to add a hook in sys_socket() to change the protocol id
from IPPROTO_TCP (or 0) to IPPROTO_MPTCP.

[1]
https://github.com/multipath-tcp/mptcp_net-next/wiki
[2]
https://github.com/multipath-tcp/mptcp_net-next/issues/79

v14:
 - Use getsockopt(MPTCP_INFO) to verify mptcp protocol intead of using
nstat command.

v13:
 - drop "Use random netns name for mptcp" patch.

v12:
 - update diag_* log of update_socket_protocol.
 - add 'ip netns show' after 'ip netns del' to check if there is
a test did not clean up its netns.
 - return libbpf_get_error() instead of -EIO for the error from
open_and_load().
 - Use getsockopt(SOL_PROTOCOL) to verify mptcp protocol intead of
using 'ss -tOni'.

v11:
 - add comments about outputs of 'ss' and 'nstat'.
 - use "err = verify_mptcpify()" instead of using =+.

v10:
 - drop "#ifdef CONFIG_BPF_JIT".
 - include vmlinux.h and bpf_tracing_net.h to avoid defining some
macros.
 - drop unneeded checks for mptcp.

v9:
 - update comment for 'update_socket_protocol'.

v8:
 - drop the additional checks on the 'protocol' value after the
'update_socket_protocol()' call.

v7:
 - add __weak and __diag_* for update_socket_protocol.

v6:
 - add update_socket_protocol.

v5:
 - add bpf_mptcpify helper.

v4:
 - use lsm_cgroup/socket_create

v3:
 - patch 8: char cmd[128]; -> char cmd[256];

v2:
 - Fix build selftests errors reported by CI

Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/79

Geliang Tang (4):
  bpf: Add update_socket_protocol hook
  selftests/bpf: Add two mptcp netns helpers
  selftests/bpf: Fix error checks of mptcp open_and_load
  selftests/bpf: Add mptcpify test

 net/mptcp/bpf.c                               |  15 ++
 net/socket.c                                  |  26 ++-
 .../testing/selftests/bpf/prog_tests/mptcp.c  | 155 +++++++++++++++---
 tools/testing/selftests/bpf/progs/mptcpify.c  |  20 +++
 4 files changed, 196 insertions(+), 20 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/mptcpify.c

-- 
2.35.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH bpf-next v14 1/4] bpf: Add update_socket_protocol hook
  2023-08-16  1:11 [PATCH bpf-next v14 0/4] bpf: Force to MPTCP Geliang Tang
@ 2023-08-16  1:11 ` Geliang Tang
  2023-08-18  8:24   ` Geliang Tang
  2023-08-16  1:11 ` [PATCH bpf-next v14 2/4] selftests/bpf: Add two mptcp netns helpers Geliang Tang
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Geliang Tang @ 2023-08-16  1:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, Florent Revest,
	Brendan Jackman, Matthieu Baerts, Mat Martineau, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, John Johansen,
	Paul Moore, James Morris, Serge E. Hallyn, Stephen Smalley,
	Eric Paris, Mykola Lysenko, Shuah Khan, Simon Horman
  Cc: Geliang Tang, bpf, netdev, mptcp, linux-security-module, selinux,
	linux-kselftest, Yonghong Song

Add a hook named update_socket_protocol in __sys_socket(), for bpf
progs to attach to and update socket protocol. One user case is to
force legacy TCP apps to create and use MPTCP sockets instead of
TCP ones.

Define a fmod_ret set named bpf_mptcp_fmodret_ids, add the hook
update_socket_protocol into this set, and register it in
bpf_mptcp_kfunc_init().

Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/79
Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
 net/mptcp/bpf.c | 15 +++++++++++++++
 net/socket.c    | 26 +++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c
index 5a0a84ad94af..8a16672b94e2 100644
--- a/net/mptcp/bpf.c
+++ b/net/mptcp/bpf.c
@@ -19,3 +19,18 @@ struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk)
 
 	return NULL;
 }
+
+BTF_SET8_START(bpf_mptcp_fmodret_ids)
+BTF_ID_FLAGS(func, update_socket_protocol)
+BTF_SET8_END(bpf_mptcp_fmodret_ids)
+
+static const struct btf_kfunc_id_set bpf_mptcp_fmodret_set = {
+	.owner = THIS_MODULE,
+	.set   = &bpf_mptcp_fmodret_ids,
+};
+
+static int __init bpf_mptcp_kfunc_init(void)
+{
+	return register_btf_fmodret_id_set(&bpf_mptcp_fmodret_set);
+}
+late_initcall(bpf_mptcp_kfunc_init);
diff --git a/net/socket.c b/net/socket.c
index 5d4e37595e9a..fdb5233bf560 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1657,12 +1657,36 @@ struct file *__sys_socket_file(int family, int type, int protocol)
 	return sock_alloc_file(sock, flags, NULL);
 }
 
+/*	A hook for bpf progs to attach to and update socket protocol.
+ *
+ *	A static noinline declaration here could cause the compiler to
+ *	optimize away the function. A global noinline declaration will
+ *	keep the definition, but may optimize away the callsite.
+ *	Therefore, __weak is needed to ensure that the call is still
+ *	emitted, by telling the compiler that we don't know what the
+ *	function might eventually be.
+ *
+ *	__diag_* below are needed to dismiss the missing prototype warning.
+ */
+
+__diag_push();
+__diag_ignore_all("-Wmissing-prototypes",
+		  "A fmod_ret entry point for BPF programs");
+
+__weak noinline int update_socket_protocol(int family, int type, int protocol)
+{
+	return protocol;
+}
+
+__diag_pop();
+
 int __sys_socket(int family, int type, int protocol)
 {
 	struct socket *sock;
 	int flags;
 
-	sock = __sys_socket_create(family, type, protocol);
+	sock = __sys_socket_create(family, type,
+				   update_socket_protocol(family, type, protocol));
 	if (IS_ERR(sock))
 		return PTR_ERR(sock);
 
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH bpf-next v14 2/4] selftests/bpf: Add two mptcp netns helpers
  2023-08-16  1:11 [PATCH bpf-next v14 0/4] bpf: Force to MPTCP Geliang Tang
  2023-08-16  1:11 ` [PATCH bpf-next v14 1/4] bpf: Add update_socket_protocol hook Geliang Tang
@ 2023-08-16  1:11 ` Geliang Tang
  2023-08-16  1:11 ` [PATCH bpf-next v14 3/4] selftests/bpf: Fix error checks of mptcp open_and_load Geliang Tang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Geliang Tang @ 2023-08-16  1:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, Florent Revest,
	Brendan Jackman, Matthieu Baerts, Mat Martineau, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, John Johansen,
	Paul Moore, James Morris, Serge E. Hallyn, Stephen Smalley,
	Eric Paris, Mykola Lysenko, Shuah Khan, Simon Horman
  Cc: Geliang Tang, bpf, netdev, mptcp, linux-security-module, selinux,
	linux-kselftest, Yonghong Song

Add two netns helpers for mptcp tests: create_netns() and
cleanup_netns(). Use them in test_base().

These new helpers will be re-used in the following commits
introducing new tests.

Acked-by: Yonghong Song <yonghong.song@linux.dev>
Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
 .../testing/selftests/bpf/prog_tests/mptcp.c  | 31 +++++++++++++------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c
index cd0c42fff7c0..76afb5191772 100644
--- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
+++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
@@ -22,6 +22,24 @@ struct mptcp_storage {
 	char ca_name[TCP_CA_NAME_MAX];
 };
 
+static struct nstoken *create_netns(void)
+{
+	SYS(fail, "ip netns add %s", NS_TEST);
+	SYS(fail, "ip -net %s link set dev lo up", NS_TEST);
+
+	return open_netns(NS_TEST);
+fail:
+	return NULL;
+}
+
+static void cleanup_netns(struct nstoken *nstoken)
+{
+	if (nstoken)
+		close_netns(nstoken);
+
+	SYS_NOFAIL("ip netns del %s &> /dev/null", NS_TEST);
+}
+
 static int verify_tsk(int map_fd, int client_fd)
 {
 	int err, cfd = client_fd;
@@ -147,11 +165,8 @@ static void test_base(void)
 	if (!ASSERT_GE(cgroup_fd, 0, "test__join_cgroup"))
 		return;
 
-	SYS(fail, "ip netns add %s", NS_TEST);
-	SYS(fail, "ip -net %s link set dev lo up", NS_TEST);
-
-	nstoken = open_netns(NS_TEST);
-	if (!ASSERT_OK_PTR(nstoken, "open_netns"))
+	nstoken = create_netns();
+	if (!ASSERT_OK_PTR(nstoken, "create_netns"))
 		goto fail;
 
 	/* without MPTCP */
@@ -174,11 +189,7 @@ static void test_base(void)
 	close(server_fd);
 
 fail:
-	if (nstoken)
-		close_netns(nstoken);
-
-	SYS_NOFAIL("ip netns del " NS_TEST " &> /dev/null");
-
+	cleanup_netns(nstoken);
 	close(cgroup_fd);
 }
 
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH bpf-next v14 3/4] selftests/bpf: Fix error checks of mptcp open_and_load
  2023-08-16  1:11 [PATCH bpf-next v14 0/4] bpf: Force to MPTCP Geliang Tang
  2023-08-16  1:11 ` [PATCH bpf-next v14 1/4] bpf: Add update_socket_protocol hook Geliang Tang
  2023-08-16  1:11 ` [PATCH bpf-next v14 2/4] selftests/bpf: Add two mptcp netns helpers Geliang Tang
@ 2023-08-16  1:11 ` Geliang Tang
  2023-08-16  1:11 ` [PATCH bpf-next v14 4/4] selftests/bpf: Add mptcpify test Geliang Tang
  2023-08-16 19:00 ` [PATCH bpf-next v14 0/4] bpf: Force to MPTCP patchwork-bot+netdevbpf
  4 siblings, 0 replies; 9+ messages in thread
From: Geliang Tang @ 2023-08-16  1:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, Florent Revest,
	Brendan Jackman, Matthieu Baerts, Mat Martineau, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, John Johansen,
	Paul Moore, James Morris, Serge E. Hallyn, Stephen Smalley,
	Eric Paris, Mykola Lysenko, Shuah Khan, Simon Horman
  Cc: Geliang Tang, bpf, netdev, mptcp, linux-security-module, selinux,
	linux-kselftest, Yonghong Song

Return libbpf_get_error(), instead of -EIO, for the error from
mptcp_sock__open_and_load().

Load success means prog_fd and map_fd are always valid. So drop these
unneeded ASSERT_GE checks for them in mptcp run_test().

Acked-by: Yonghong Song <yonghong.song@linux.dev>
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
 tools/testing/selftests/bpf/prog_tests/mptcp.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c
index 76afb5191772..3d3999067e27 100644
--- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
+++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
@@ -118,24 +118,14 @@ static int run_test(int cgroup_fd, int server_fd, bool is_mptcp)
 
 	sock_skel = mptcp_sock__open_and_load();
 	if (!ASSERT_OK_PTR(sock_skel, "skel_open_load"))
-		return -EIO;
+		return libbpf_get_error(sock_skel);
 
 	err = mptcp_sock__attach(sock_skel);
 	if (!ASSERT_OK(err, "skel_attach"))
 		goto out;
 
 	prog_fd = bpf_program__fd(sock_skel->progs._sockops);
-	if (!ASSERT_GE(prog_fd, 0, "bpf_program__fd")) {
-		err = -EIO;
-		goto out;
-	}
-
 	map_fd = bpf_map__fd(sock_skel->maps.socket_storage_map);
-	if (!ASSERT_GE(map_fd, 0, "bpf_map__fd")) {
-		err = -EIO;
-		goto out;
-	}
-
 	err = bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS, 0);
 	if (!ASSERT_OK(err, "bpf_prog_attach"))
 		goto out;
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH bpf-next v14 4/4] selftests/bpf: Add mptcpify test
  2023-08-16  1:11 [PATCH bpf-next v14 0/4] bpf: Force to MPTCP Geliang Tang
                   ` (2 preceding siblings ...)
  2023-08-16  1:11 ` [PATCH bpf-next v14 3/4] selftests/bpf: Fix error checks of mptcp open_and_load Geliang Tang
@ 2023-08-16  1:11 ` Geliang Tang
  2023-08-16 18:59   ` Martin KaFai Lau
  2023-08-16 19:00 ` [PATCH bpf-next v14 0/4] bpf: Force to MPTCP patchwork-bot+netdevbpf
  4 siblings, 1 reply; 9+ messages in thread
From: Geliang Tang @ 2023-08-16  1:11 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, Florent Revest,
	Brendan Jackman, Matthieu Baerts, Mat Martineau, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, John Johansen,
	Paul Moore, James Morris, Serge E. Hallyn, Stephen Smalley,
	Eric Paris, Mykola Lysenko, Shuah Khan, Simon Horman
  Cc: Geliang Tang, bpf, netdev, mptcp, linux-security-module, selinux,
	linux-kselftest, Yonghong Song

Implement a new test program mptcpify: if the family is AF_INET or
AF_INET6, the type is SOCK_STREAM, and the protocol ID is 0 or
IPPROTO_TCP, set it to IPPROTO_MPTCP. It will be hooked in
update_socket_protocol().

Extend the MPTCP test base, add a selftest test_mptcpify() for the
mptcpify case. Open and load the mptcpify test prog to mptcpify the
TCP sockets dynamically, then use start_server() and connect_to_fd()
to create a TCP socket, but actually what's created is an MPTCP
socket, which can be verified through 'getsockopt(SOL_PROTOCOL)'
and 'getsockopt(MPTCP_INFO)'.

Acked-by: Yonghong Song <yonghong.song@linux.dev>
Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
 .../testing/selftests/bpf/prog_tests/mptcp.c  | 116 ++++++++++++++++++
 tools/testing/selftests/bpf/progs/mptcpify.c  |  20 +++
 2 files changed, 136 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/progs/mptcpify.c

diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c
index 3d3999067e27..68ebf9735e16 100644
--- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
+++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
@@ -2,13 +2,30 @@
 /* Copyright (c) 2020, Tessares SA. */
 /* Copyright (c) 2022, SUSE. */
 
+#include <linux/mptcp.h>
+#include <netinet/in.h>
 #include <test_progs.h>
 #include "cgroup_helpers.h"
 #include "network_helpers.h"
 #include "mptcp_sock.skel.h"
+#include "mptcpify.skel.h"
 
 #define NS_TEST "mptcp_ns"
 
+#ifndef IPPROTO_MPTCP
+#define IPPROTO_MPTCP 262
+#endif
+
+#ifndef MPTCP_INFO
+#define MPTCP_INFO		1
+#endif
+#ifndef MPTCP_INFO_FLAG_FALLBACK
+#define MPTCP_INFO_FLAG_FALLBACK		_BITUL(0)
+#endif
+#ifndef MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED
+#define MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED	_BITUL(1)
+#endif
+
 #ifndef TCP_CA_NAME_MAX
 #define TCP_CA_NAME_MAX	16
 #endif
@@ -183,8 +200,107 @@ static void test_base(void)
 	close(cgroup_fd);
 }
 
+static void send_byte(int fd)
+{
+	char b = 0x55;
+
+	ASSERT_EQ(write(fd, &b, sizeof(b)), 1, "send single byte");
+}
+
+static int verify_mptcpify(int server_fd, int client_fd)
+{
+	struct mptcp_info info;
+	socklen_t optlen;
+	int protocol;
+	int err = 0;
+
+	optlen = sizeof(protocol);
+	if (!ASSERT_OK(getsockopt(server_fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &optlen),
+		       "getsockopt(SOL_PROTOCOL)"))
+		return -1;
+
+	if (!ASSERT_EQ(protocol, IPPROTO_MPTCP, "protocol isn't MPTCP"))
+		err++;
+
+	optlen = sizeof(info);
+	if (!ASSERT_OK(getsockopt(client_fd, SOL_MPTCP, MPTCP_INFO, &info, &optlen),
+		       "getsockopt(MPTCP_INFO)"))
+		return -1;
+
+	if (!ASSERT_GE(info.mptcpi_flags, 0, "unexpected mptcpi_flags"))
+		err++;
+	if (!ASSERT_FALSE(info.mptcpi_flags & MPTCP_INFO_FLAG_FALLBACK,
+			  "MPTCP fallback"))
+		err++;
+	if (!ASSERT_TRUE(info.mptcpi_flags & MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED,
+			 "no remote key received"))
+		err++;
+
+	return err;
+}
+
+static int run_mptcpify(int cgroup_fd)
+{
+	int server_fd, client_fd, err = 0;
+	struct mptcpify *mptcpify_skel;
+
+	mptcpify_skel = mptcpify__open_and_load();
+	if (!ASSERT_OK_PTR(mptcpify_skel, "skel_open_load"))
+		return libbpf_get_error(mptcpify_skel);
+
+	err = mptcpify__attach(mptcpify_skel);
+	if (!ASSERT_OK(err, "skel_attach"))
+		goto out;
+
+	/* without MPTCP */
+	server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0);
+	if (!ASSERT_GE(server_fd, 0, "start_server")) {
+		err = -EIO;
+		goto out;
+	}
+
+	client_fd = connect_to_fd(server_fd, 0);
+	if (!ASSERT_GE(client_fd, 0, "connect to fd")) {
+		err = -EIO;
+		goto close_server;
+	}
+
+	send_byte(client_fd);
+
+	err = verify_mptcpify(server_fd, client_fd);
+
+	close(client_fd);
+close_server:
+	close(server_fd);
+out:
+	mptcpify__destroy(mptcpify_skel);
+	return err;
+}
+
+static void test_mptcpify(void)
+{
+	struct nstoken *nstoken = NULL;
+	int cgroup_fd;
+
+	cgroup_fd = test__join_cgroup("/mptcpify");
+	if (!ASSERT_GE(cgroup_fd, 0, "test__join_cgroup"))
+		return;
+
+	nstoken = create_netns();
+	if (!ASSERT_OK_PTR(nstoken, "create_netns"))
+		goto fail;
+
+	ASSERT_OK(run_mptcpify(cgroup_fd), "run_mptcpify");
+
+fail:
+	cleanup_netns(nstoken);
+	close(cgroup_fd);
+}
+
 void test_mptcp(void)
 {
 	if (test__start_subtest("base"))
 		test_base();
+	if (test__start_subtest("mptcpify"))
+		test_mptcpify();
 }
diff --git a/tools/testing/selftests/bpf/progs/mptcpify.c b/tools/testing/selftests/bpf/progs/mptcpify.c
new file mode 100644
index 000000000000..53301ae8a8f7
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/mptcpify.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2023, SUSE. */
+
+#include "vmlinux.h"
+#include <bpf/bpf_tracing.h>
+#include "bpf_tracing_net.h"
+
+char _license[] SEC("license") = "GPL";
+
+SEC("fmod_ret/update_socket_protocol")
+int BPF_PROG(mptcpify, int family, int type, int protocol)
+{
+	if ((family == AF_INET || family == AF_INET6) &&
+	    type == SOCK_STREAM &&
+	    (!protocol || protocol == IPPROTO_TCP)) {
+		return IPPROTO_MPTCP;
+	}
+
+	return protocol;
+}
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH bpf-next v14 4/4] selftests/bpf: Add mptcpify test
  2023-08-16  1:11 ` [PATCH bpf-next v14 4/4] selftests/bpf: Add mptcpify test Geliang Tang
@ 2023-08-16 18:59   ` Martin KaFai Lau
  0 siblings, 0 replies; 9+ messages in thread
From: Martin KaFai Lau @ 2023-08-16 18:59 UTC (permalink / raw)
  To: Geliang Tang
  Cc: bpf, netdev, mptcp, linux-security-module, selinux,
	linux-kselftest, Yonghong Song, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Song Liu, Yonghong Song,
	John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Florent Revest, Brendan Jackman, Matthieu Baerts, Mat Martineau,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley, Eric Paris, Mykola Lysenko, Shuah Khan,
	Simon Horman

On 8/15/23 6:11 PM, Geliang Tang wrote:
> Implement a new test program mptcpify: if the family is AF_INET or
> AF_INET6, the type is SOCK_STREAM, and the protocol ID is 0 or
> IPPROTO_TCP, set it to IPPROTO_MPTCP. It will be hooked in
> update_socket_protocol().
> 
> Extend the MPTCP test base, add a selftest test_mptcpify() for the
> mptcpify case. Open and load the mptcpify test prog to mptcpify the
> TCP sockets dynamically, then use start_server() and connect_to_fd()
> to create a TCP socket, but actually what's created is an MPTCP
> socket, which can be verified through 'getsockopt(SOL_PROTOCOL)'
> and 'getsockopt(MPTCP_INFO)'.
> 
> Acked-by: Yonghong Song <yonghong.song@linux.dev>
> Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
> Signed-off-by: Geliang Tang <geliang.tang@suse.com>
> ---
>   .../testing/selftests/bpf/prog_tests/mptcp.c  | 116 ++++++++++++++++++
>   tools/testing/selftests/bpf/progs/mptcpify.c  |  20 +++
>   2 files changed, 136 insertions(+)
>   create mode 100644 tools/testing/selftests/bpf/progs/mptcpify.c
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c
> index 3d3999067e27..68ebf9735e16 100644
> --- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
> +++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
> @@ -2,13 +2,30 @@
>   /* Copyright (c) 2020, Tessares SA. */
>   /* Copyright (c) 2022, SUSE. */
>   
> +#include <linux/mptcp.h>
bpf CI failed 
(https://github.com/kernel-patches/bpf/actions/runs/5882006207/job/15951617063):

   /tmp/work/bpf/bpf/tools/testing/selftests/bpf/prog_tests/mptcp.c:5:10: fatal 
error: 'linux/mptcp.h' file not found
   #include <linux/mptcp.h>

I fixed that by copying the 'struct mptcp_info' but renamed to 'struct 
__mptcp_info' just in case any fallout in the future.

My environment also does not have SOL_MPTCP, so I do an ifndef for it also.

> +#include <netinet/in.h>
>   #include <test_progs.h>
>   #include "cgroup_helpers.h"
>   #include "network_helpers.h"
>   #include "mptcp_sock.skel.h"
> +#include "mptcpify.skel.h"
>   
>   #define NS_TEST "mptcp_ns"
>   
> +#ifndef IPPROTO_MPTCP
> +#define IPPROTO_MPTCP 262
> +#endif
> +
> +#ifndef MPTCP_INFO
> +#define MPTCP_INFO		1
> +#endif
> +#ifndef MPTCP_INFO_FLAG_FALLBACK
> +#define MPTCP_INFO_FLAG_FALLBACK		_BITUL(0)

I have to add '#include <linux/const.h>' for the _BITUL() here also....

The set is applied. Please follow up if I make mistake on those fixes.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH bpf-next v14 0/4] bpf: Force to MPTCP
  2023-08-16  1:11 [PATCH bpf-next v14 0/4] bpf: Force to MPTCP Geliang Tang
                   ` (3 preceding siblings ...)
  2023-08-16  1:11 ` [PATCH bpf-next v14 4/4] selftests/bpf: Add mptcpify test Geliang Tang
@ 2023-08-16 19:00 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 9+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-08-16 19:00 UTC (permalink / raw)
  To: Geliang Tang
  Cc: ast, daniel, andrii, martin.lau, song, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, revest, jackmanb, matthieu.baerts,
	martineau, davem, edumazet, kuba, pabeni, john.johansen, paul,
	jmorris, serge, stephen.smalley.work, eparis, mykolal, shuah,
	horms, bpf, netdev, mptcp, linux-security-module, selinux,
	linux-kselftest

Hello:

This series was applied to bpf/bpf-next.git (master)
by Martin KaFai Lau <martin.lau@kernel.org>:

On Wed, 16 Aug 2023 09:11:55 +0800 you wrote:
> As is described in the "How to use MPTCP?" section in MPTCP wiki [1]:
> 
> "Your app should create sockets with IPPROTO_MPTCP as the proto:
> ( socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); ). Legacy apps can be
> forced to create and use MPTCP sockets instead of TCP ones via the
> mptcpize command bundled with the mptcpd daemon."
> 
> [...]

Here is the summary with links:
  - [bpf-next,v14,1/4] bpf: Add update_socket_protocol hook
    https://git.kernel.org/bpf/bpf-next/c/0dd061a6a115
  - [bpf-next,v14,2/4] selftests/bpf: Add two mptcp netns helpers
    https://git.kernel.org/bpf/bpf-next/c/97c9c652089b
  - [bpf-next,v14,3/4] selftests/bpf: Fix error checks of mptcp open_and_load
    https://git.kernel.org/bpf/bpf-next/c/207746550262
  - [bpf-next,v14,4/4] selftests/bpf: Add mptcpify test
    https://git.kernel.org/bpf/bpf-next/c/ddba122428a7

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH bpf-next v14 1/4] bpf: Add update_socket_protocol hook
  2023-08-16  1:11 ` [PATCH bpf-next v14 1/4] bpf: Add update_socket_protocol hook Geliang Tang
@ 2023-08-18  8:24   ` Geliang Tang
  2023-08-18 15:26     ` Yonghong Song
  0 siblings, 1 reply; 9+ messages in thread
From: Geliang Tang @ 2023-08-18  8:24 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, Florent Revest,
	Brendan Jackman, Matthieu Baerts, Mat Martineau, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, John Johansen,
	Paul Moore, James Morris, Serge E. Hallyn, Stephen Smalley,
	Eric Paris, Mykola Lysenko, Shuah Khan, Simon Horman
  Cc: bpf, netdev, mptcp, linux-security-module, selinux,
	linux-kselftest

On Wed, Aug 16, 2023 at 09:11:56AM +0800, Geliang Tang wrote:
> Add a hook named update_socket_protocol in __sys_socket(), for bpf
> progs to attach to and update socket protocol. One user case is to
> force legacy TCP apps to create and use MPTCP sockets instead of
> TCP ones.
> 
> Define a fmod_ret set named bpf_mptcp_fmodret_ids, add the hook
> update_socket_protocol into this set, and register it in
> bpf_mptcp_kfunc_init().
> 
> Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/79
> Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
> Acked-by: Yonghong Song <yonghong.song@linux.dev>
> Signed-off-by: Geliang Tang <geliang.tang@suse.com>
> ---
>  net/mptcp/bpf.c | 15 +++++++++++++++
>  net/socket.c    | 26 +++++++++++++++++++++++++-
>  2 files changed, 40 insertions(+), 1 deletion(-)
> 
> diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c
> index 5a0a84ad94af..8a16672b94e2 100644
> --- a/net/mptcp/bpf.c
> +++ b/net/mptcp/bpf.c
> @@ -19,3 +19,18 @@ struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk)
>  
>  	return NULL;
>  }
> +
> +BTF_SET8_START(bpf_mptcp_fmodret_ids)
> +BTF_ID_FLAGS(func, update_socket_protocol)
> +BTF_SET8_END(bpf_mptcp_fmodret_ids)
> +
> +static const struct btf_kfunc_id_set bpf_mptcp_fmodret_set = {
> +	.owner = THIS_MODULE,
> +	.set   = &bpf_mptcp_fmodret_ids,
> +};
> +
> +static int __init bpf_mptcp_kfunc_init(void)
> +{
> +	return register_btf_fmodret_id_set(&bpf_mptcp_fmodret_set);
> +}
> +late_initcall(bpf_mptcp_kfunc_init);
> diff --git a/net/socket.c b/net/socket.c
> index 5d4e37595e9a..fdb5233bf560 100644
> --- a/net/socket.c
> +++ b/net/socket.c
> @@ -1657,12 +1657,36 @@ struct file *__sys_socket_file(int family, int type, int protocol)
>  	return sock_alloc_file(sock, flags, NULL);
>  }
>  
> +/*	A hook for bpf progs to attach to and update socket protocol.
> + *
> + *	A static noinline declaration here could cause the compiler to
> + *	optimize away the function. A global noinline declaration will
> + *	keep the definition, but may optimize away the callsite.
> + *	Therefore, __weak is needed to ensure that the call is still
> + *	emitted, by telling the compiler that we don't know what the
> + *	function might eventually be.
> + *
> + *	__diag_* below are needed to dismiss the missing prototype warning.
> + */
> +
> +__diag_push();
> +__diag_ignore_all("-Wmissing-prototypes",
> +		  "A fmod_ret entry point for BPF programs");

Hi Martin & Yonghong,

I got a sparse warning for this new added 'update_socket_protocol':

 > touch net/socket.c && make C=1 net/socket.o

 net/socket.c:1676:21: warning: symbol 'update_socket_protocol' was not declared. Should it be static?

What should I do to fix it, or should I just leave it here? Please give
me some suggestions.

Thanks,
-Geliang

> +
> +__weak noinline int update_socket_protocol(int family, int type, int protocol)
> +{
> +	return protocol;
> +}
> +
> +__diag_pop();
> +
>  int __sys_socket(int family, int type, int protocol)
>  {
>  	struct socket *sock;
>  	int flags;
>  
> -	sock = __sys_socket_create(family, type, protocol);
> +	sock = __sys_socket_create(family, type,
> +				   update_socket_protocol(family, type, protocol));
>  	if (IS_ERR(sock))
>  		return PTR_ERR(sock);
>  
> -- 
> 2.35.3
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH bpf-next v14 1/4] bpf: Add update_socket_protocol hook
  2023-08-18  8:24   ` Geliang Tang
@ 2023-08-18 15:26     ` Yonghong Song
  0 siblings, 0 replies; 9+ messages in thread
From: Yonghong Song @ 2023-08-18 15:26 UTC (permalink / raw)
  To: Geliang Tang, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, Yonghong Song,
	John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Florent Revest, Brendan Jackman, Matthieu Baerts, Mat Martineau,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley, Eric Paris, Mykola Lysenko, Shuah Khan,
	Simon Horman
  Cc: bpf, netdev, mptcp, linux-security-module, selinux,
	linux-kselftest



On 8/18/23 1:24 AM, Geliang Tang wrote:
> On Wed, Aug 16, 2023 at 09:11:56AM +0800, Geliang Tang wrote:
>> Add a hook named update_socket_protocol in __sys_socket(), for bpf
>> progs to attach to and update socket protocol. One user case is to
>> force legacy TCP apps to create and use MPTCP sockets instead of
>> TCP ones.
>>
>> Define a fmod_ret set named bpf_mptcp_fmodret_ids, add the hook
>> update_socket_protocol into this set, and register it in
>> bpf_mptcp_kfunc_init().
>>
>> Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/79
>> Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
>> Acked-by: Yonghong Song <yonghong.song@linux.dev>
>> Signed-off-by: Geliang Tang <geliang.tang@suse.com>
>> ---
>>   net/mptcp/bpf.c | 15 +++++++++++++++
>>   net/socket.c    | 26 +++++++++++++++++++++++++-
>>   2 files changed, 40 insertions(+), 1 deletion(-)
>>
>> diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c
>> index 5a0a84ad94af..8a16672b94e2 100644
>> --- a/net/mptcp/bpf.c
>> +++ b/net/mptcp/bpf.c
>> @@ -19,3 +19,18 @@ struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk)
>>   
>>   	return NULL;
>>   }
>> +
>> +BTF_SET8_START(bpf_mptcp_fmodret_ids)
>> +BTF_ID_FLAGS(func, update_socket_protocol)
>> +BTF_SET8_END(bpf_mptcp_fmodret_ids)
>> +
>> +static const struct btf_kfunc_id_set bpf_mptcp_fmodret_set = {
>> +	.owner = THIS_MODULE,
>> +	.set   = &bpf_mptcp_fmodret_ids,
>> +};
>> +
>> +static int __init bpf_mptcp_kfunc_init(void)
>> +{
>> +	return register_btf_fmodret_id_set(&bpf_mptcp_fmodret_set);
>> +}
>> +late_initcall(bpf_mptcp_kfunc_init);
>> diff --git a/net/socket.c b/net/socket.c
>> index 5d4e37595e9a..fdb5233bf560 100644
>> --- a/net/socket.c
>> +++ b/net/socket.c
>> @@ -1657,12 +1657,36 @@ struct file *__sys_socket_file(int family, int type, int protocol)
>>   	return sock_alloc_file(sock, flags, NULL);
>>   }
>>   
>> +/*	A hook for bpf progs to attach to and update socket protocol.
>> + *
>> + *	A static noinline declaration here could cause the compiler to
>> + *	optimize away the function. A global noinline declaration will
>> + *	keep the definition, but may optimize away the callsite.
>> + *	Therefore, __weak is needed to ensure that the call is still
>> + *	emitted, by telling the compiler that we don't know what the
>> + *	function might eventually be.
>> + *
>> + *	__diag_* below are needed to dismiss the missing prototype warning.
>> + */
>> +
>> +__diag_push();
>> +__diag_ignore_all("-Wmissing-prototypes",
>> +		  "A fmod_ret entry point for BPF programs");
> 
> Hi Martin & Yonghong,
> 
> I got a sparse warning for this new added 'update_socket_protocol':
> 
>   > touch net/socket.c && make C=1 net/socket.o
> 
>   net/socket.c:1676:21: warning: symbol 'update_socket_protocol' was not declared. Should it be static?

This is a sparse warning. Let us ignore it for now. We already have
__diag_ignore for missing prototypes in the above, but sparse won't 
recognize them. Also, 'static' is conflict with '__weak' attribute,
and we cannot remove '__weak' attribute.

> 
> What should I do to fix it, or should I just leave it here? Please give
> me some suggestions.
> 
> Thanks,
> -Geliang
> 
>> +
>> +__weak noinline int update_socket_protocol(int family, int type, int protocol)
>> +{
>> +	return protocol;
>> +}
>> +
>> +__diag_pop();
>> +
>>   int __sys_socket(int family, int type, int protocol)
>>   {
>>   	struct socket *sock;
>>   	int flags;
>>   
>> -	sock = __sys_socket_create(family, type, protocol);
>> +	sock = __sys_socket_create(family, type,
>> +				   update_socket_protocol(family, type, protocol));
>>   	if (IS_ERR(sock))
>>   		return PTR_ERR(sock);
>>   
>> -- 
>> 2.35.3
>>
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-08-18 15:26 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-16  1:11 [PATCH bpf-next v14 0/4] bpf: Force to MPTCP Geliang Tang
2023-08-16  1:11 ` [PATCH bpf-next v14 1/4] bpf: Add update_socket_protocol hook Geliang Tang
2023-08-18  8:24   ` Geliang Tang
2023-08-18 15:26     ` Yonghong Song
2023-08-16  1:11 ` [PATCH bpf-next v14 2/4] selftests/bpf: Add two mptcp netns helpers Geliang Tang
2023-08-16  1:11 ` [PATCH bpf-next v14 3/4] selftests/bpf: Fix error checks of mptcp open_and_load Geliang Tang
2023-08-16  1:11 ` [PATCH bpf-next v14 4/4] selftests/bpf: Add mptcpify test Geliang Tang
2023-08-16 18:59   ` Martin KaFai Lau
2023-08-16 19:00 ` [PATCH bpf-next v14 0/4] bpf: Force to MPTCP patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).