Message ID | 1effb0a793140532be749aebbd7912798245745e.1691125344.git.geliang.tang@suse.com (mailing list archive) |
---|---|
State | Handled Elsewhere |
Headers | show |
Series | bpf: Force to MPTCP | expand |
On 8/3/23 10:07 PM, Geliang Tang wrote: > diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c > index 3dc0ba2e7590..e6aafb4cfa8e 100644 > --- a/tools/testing/selftests/bpf/prog_tests/mptcp.c > +++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c > @@ -6,6 +6,7 @@ > #include "cgroup_helpers.h" > #include "network_helpers.h" > #include "mptcp_sock.skel.h" > +#include "mptcpify.skel.h" > > char NS_TEST[32]; > > @@ -185,8 +186,105 @@ 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(void) > +{ > + char cmd[256]; > + int err = 0; > + > + /* Output of ss: > + * > + * ESTAB 0 0 127.0.0.1:44180 127.0.0.1:42225 cubic > + * ... tcp-ulp-mptcp flags:Mmec ... > + */ > + snprintf(cmd, sizeof(cmd), > + "ip netns exec %s ss -tOni | grep -q '%s'", > + NS_TEST, "tcp-ulp-mptcp"); > + if (!ASSERT_OK(system(cmd), "No tcp-ulp-mptcp found!")) > + err++; > + > + /* Output of nstat: > + * > + * #kernel > + * MPTcpExtMPCapableSYNACKRX 1 0.0 > + */ > + snprintf(cmd, sizeof(cmd), > + "ip netns exec %s nstat -asz %s | awk '%s' | grep -q '%s'", > + NS_TEST, "MPTcpExtMPCapableSYNACKRX", > + "NR==1 {next} {print $2}", "1"); > + if (!ASSERT_OK(system(cmd), "No MPTcpExtMPCapableSYNACKRX found!")) > + err++; The idea is to confirm the protocol has been changed. Is it more direct to use getsockopt(SO_PROTOCOL) on the created fd(s)? > + > + 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 -EIO; Although the return value does not matter much, -EIO looks weird for the error from mptcpify__open_and_load(). May be 'return libbpf_get_error(mptcpify_skel);' -- pw-bot: cr > + > + 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(); > + > + close(client_fd); > +close_server: > + close(server_fd); > +out: > + mptcpify__destroy(mptcpify_skel); > + return err; > +} > +
diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c index 3dc0ba2e7590..e6aafb4cfa8e 100644 --- a/tools/testing/selftests/bpf/prog_tests/mptcp.c +++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c @@ -6,6 +6,7 @@ #include "cgroup_helpers.h" #include "network_helpers.h" #include "mptcp_sock.skel.h" +#include "mptcpify.skel.h" char NS_TEST[32]; @@ -185,8 +186,105 @@ 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(void) +{ + char cmd[256]; + int err = 0; + + /* Output of ss: + * + * ESTAB 0 0 127.0.0.1:44180 127.0.0.1:42225 cubic + * ... tcp-ulp-mptcp flags:Mmec ... + */ + snprintf(cmd, sizeof(cmd), + "ip netns exec %s ss -tOni | grep -q '%s'", + NS_TEST, "tcp-ulp-mptcp"); + if (!ASSERT_OK(system(cmd), "No tcp-ulp-mptcp found!")) + err++; + + /* Output of nstat: + * + * #kernel + * MPTcpExtMPCapableSYNACKRX 1 0.0 + */ + snprintf(cmd, sizeof(cmd), + "ip netns exec %s nstat -asz %s | awk '%s' | grep -q '%s'", + NS_TEST, "MPTcpExtMPCapableSYNACKRX", + "NR==1 {next} {print $2}", "1"); + if (!ASSERT_OK(system(cmd), "No MPTcpExtMPCapableSYNACKRX found!")) + 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 -EIO; + + 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(); + + 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; +}