From: Martin KaFai Lau <martin.lau@linux.dev>
To: "Alexis Lothoré (eBPF Foundation)" <alexis.lothore@bootlin.com>
Cc: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
John Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@kernel.org>,
Stanislav Fomichev <sdf@fomichev.me>, Hao Luo <haoluo@google.com>,
Jiri Olsa <jolsa@kernel.org>, Shuah Khan <shuah@kernel.org>,
ebpf@linuxfoundation.org,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
Bastien Curutchet <bastien.curutchet@bootlin.com>,
bpf@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH bpf-next 4/5] selftests/bpf: integrate test_tc_tunnel.sh tests into test_progs
Date: Fri, 17 Oct 2025 17:18:02 -0700 [thread overview]
Message-ID: <2477894b-3325-4bc2-9d3c-a066b3cbb8f6@linux.dev> (raw)
In-Reply-To: <20251017-tc_tunnel-v1-4-2d86808d86b2@bootlin.com>
On 10/17/25 7:29 AM, Alexis Lothoré (eBPF Foundation) wrote:
> The test_tc_tunnel.sh script checks that a large variety of tunneling
> mechanisms handled by the kernel can be handled as well by eBPF
> programs. While this test shares similarities with test_tunnel.c (which
> is already integrated in test_progs), those are testing slightly
> different things:
> - test_tunnel.c creates a tunnel interface, and then get and set tunnel
> keys in packet metadata, from BPF programs.
> - test_tc_tunnels.sh manually parses/crafts packets content
>
> Bring the tests covered by test_tc_tunnel.sh into the test_progs
> framework, by creating a dedicated test_tc_tunnel.sh. This new test
> defines a "generic" runner which, for each test configuration:
> - will bring the relevant veth pair, each of those isolated in a
> dedicated namespace
> - will check that traffic will fail if there is only an encapsulating
> program attached to one veth egress
> - will check that traffic succeed if we enable some decapsulation module
> on kernel side
> - will check that traffic still succeeds if we replace the kernel
> decapsulation with some eBPF ingress decapsulation.
>
> Example of the new test execution:
>
> # ./test_progs -a tc_tunnel
> #447/1 tc_tunnel/ipip_none:OK
> #447/2 tc_tunnel/ipip6_none:OK
> #447/3 tc_tunnel/ip6tnl_none:OK
> #447/4 tc_tunnel/sit_none:OK
> #447/5 tc_tunnel/vxlan_eth:OK
> #447/6 tc_tunnel/ip6vxlan_eth:OK
> #447/7 tc_tunnel/gre_none:OK
> #447/8 tc_tunnel/gre_eth:OK
> #447/9 tc_tunnel/gre_mpls:OK
> #447/10 tc_tunnel/ip6gre_none:OK
> #447/11 tc_tunnel/ip6gre_eth:OK
> #447/12 tc_tunnel/ip6gre_mpls:OK
> #447/13 tc_tunnel/udp_none:OK
> #447/14 tc_tunnel/udp_eth:OK
> #447/15 tc_tunnel/udp_mpls:OK
> #447/16 tc_tunnel/ip6udp_none:OK
> #447/17 tc_tunnel/ip6udp_eth:OK
> #447/18 tc_tunnel/ip6udp_mpls:OK
> #447 tc_tunnel:OK
> Summary: 1/18 PASSED, 0 SKIPPED, 0 FAILED
Thanks for working on this!
One high level comment is to minimize switching netns to make the test
easier to follow.
Some ideas...
> +static void stop_server(struct subtest_cfg *cfg)
> +{
> + struct nstoken *nstoken = open_netns(SERVER_NS);
> +
> + close(*cfg->server_fd);
> + cfg->server_fd = NULL;
> + close_netns(nstoken);
> +}
> +
> +static int check_server_rx_data(struct subtest_cfg *cfg,
> + struct connection *conn, int len)
> +{
> + struct nstoken *nstoken = open_netns(SERVER_NS);
> + int err;
> +
> + memset(rx_buffer, 0, BUFFER_LEN);
> + err = recv(conn->server_fd, rx_buffer, len, 0);
> + close_netns(nstoken);
> + if (!ASSERT_EQ(err, len, "check rx data len"))
> + return 1;
> + if (!ASSERT_MEMEQ(tx_buffer, rx_buffer, len, "check received data"))
> + return 1;
> + return 0;
> +}
> +
> +static struct connection *connect_client_to_server(struct subtest_cfg *cfg)
> +{
> + struct network_helper_opts opts = {.timeout_ms = 500};
> + int family = cfg->ipproto == 6 ? AF_INET6 : AF_INET;
> + struct nstoken *nstoken = open_netns(CLIENT_NS);
> + struct connection *conn = NULL;
> + int client_fd, server_fd;
> +
> + client_fd = connect_to_addr_str(family, SOCK_STREAM, cfg->server_addr,
> + TEST_PORT, &opts);
> + close_netns(nstoken);
> +
> + if (client_fd < 0)
> + return NULL;
> +
> + nstoken = open_netns(SERVER_NS);
Understood that the server is in another netns but I don't think it
needs to switch back to SERVER_NS to use its fd like accept(server_fd).
It can be done in client_ns. Please check.
The same for the above check_server_rx_data and stop_server.
> + server_fd = accept(*cfg->server_fd, NULL, NULL);
> + close_netns(nstoken);
> + if (server_fd < 0)
> + return NULL;
> +
> + conn = malloc(sizeof(struct connection));
> + if (conn) {
> + conn->server_fd = server_fd;
> + conn->client_fd = client_fd;
> + }
> +
> + return conn;
> +}
> +
> +static void disconnect_client_from_server(struct subtest_cfg *cfg,
> + struct connection *conn)
> +{
> + struct nstoken *nstoken;
> +
> + nstoken = open_netns(SERVER_NS);
same here.
> + close(conn->server_fd);
> + close_netns(nstoken);
> + nstoken = open_netns(CLIENT_NS);
and here.
> + close(conn->client_fd);
> + close_netns(nstoken);
> + free(conn);
> +}
> +
> +static int send_and_test_data(struct subtest_cfg *cfg, bool must_succeed)
See if this whole function can work in client_ns alone or may be the
caller run_test() can stay with the CLIENT_NS instead of...
> +{
> + struct nstoken *nstoken = NULL;
> + struct connection *conn;
> + int err, res = -1;
> +
> + conn = connect_client_to_server(cfg);
> + if (!must_succeed && !ASSERT_EQ(conn, NULL, "connection that must fail"))
> + goto end;
> + else if (!must_succeed)
> + return 0;
> +
> + if (!ASSERT_NEQ(conn, NULL, "connection that must succeed"))
> + return 1;
> +
> + nstoken = open_netns(CLIENT_NS);
switching here...
> + err = send(conn->client_fd, tx_buffer, DEFAULT_TEST_DATA_SIZE, 0);
> + close_netns(nstoken);
> + if (!ASSERT_EQ(err, DEFAULT_TEST_DATA_SIZE, "send data from client"))
> + goto end;
> + if (check_server_rx_data(cfg, conn, DEFAULT_TEST_DATA_SIZE))
> + goto end;
> +
> + if (!cfg->test_gso) {
> + res = 0;
> + goto end;
> + }
> +
> + nstoken = open_netns(CLIENT_NS);
and here.
> +static void run_test(struct subtest_cfg *cfg)
> +{
See if it can open_netns(CLIENT_NS) once at the beginning.
> + if (!ASSERT_OK(run_server(cfg), "run server"))
The run_server and configure_* can open/close SERVER_NS when needed.
open_netns should have saved the previous netns (i.e. CLIENT_NS) such
that it knows which one to restore during close_netns(). I don't think I
have tried that though but should work. Please check.
> + goto fail;
> +
> + // Basic communication must work
Consistent comment style. Stay with /* */
> + if (!ASSERT_OK(send_and_test_data(cfg, true), "connect without any encap"))
> + goto fail;
> +
> + // Attach encapsulation program to client, communication must fail
> + if (!ASSERT_OK(configure_encapsulation(cfg), "configure encapsulation"))
> + return;
> + if (!ASSERT_OK(send_and_test_data(cfg, false), "connect with encap prog only"))
> + goto fail;
> +
> + /* Insert kernel decap module, connection must succeed */
> + if (!ASSERT_OK(configure_kernel_decapsulation(cfg), "configure kernel decapsulation"))
> + goto fail;
> + if (!ASSERT_OK(send_and_test_data(cfg, !cfg->expect_kern_decap_failure),
> + "connect with encap prog and kern decap"))
> + goto fail;
> +
> + // Replace kernel module with BPF decap, test must pass
> + if (!ASSERT_OK(configure_ebpf_decapsulation(cfg), "configure ebpf decapsulation"))
> + goto fail;
> + ASSERT_OK(send_and_test_data(cfg, true), "connect with encap and decap progs");
> +
> +fail:
> + stop_server(cfg);
> +}
>struct subtest_cfg subtests_cfg[] = {
static
> +int subtests_count = sizeof(subtests_cfg)/sizeof(struct subtest_cfg);
ARRAY_SIZE(subtests_cfg)
pw-bot: cr
next prev parent reply other threads:[~2025-10-18 0:18 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-17 14:29 [PATCH bpf-next 0/5] selftests/bpf: convert test_tc_tunnel.sh to test_progs Alexis Lothoré (eBPF Foundation)
2025-10-17 14:29 ` [PATCH bpf-next 1/5] testing/selftests: rename tc_helpers.h to tcx_helpers.h Alexis Lothoré (eBPF Foundation)
2025-10-17 14:29 ` [PATCH bpf-next 2/5] selftests/bpf: add tc helpers Alexis Lothoré (eBPF Foundation)
2025-10-17 23:26 ` Martin KaFai Lau
2025-10-20 8:54 ` Alexis Lothoré
2025-10-17 14:29 ` [PATCH bpf-next 3/5] selftests/bpf: make test_tc_tunnel.bpf.c compatible with big endian platforms Alexis Lothoré (eBPF Foundation)
2025-10-17 23:34 ` Martin KaFai Lau
2025-10-17 14:29 ` [PATCH bpf-next 4/5] selftests/bpf: integrate test_tc_tunnel.sh tests into test_progs Alexis Lothoré (eBPF Foundation)
2025-10-18 0:18 ` Martin KaFai Lau [this message]
2025-10-19 8:45 ` Alexis Lothoré
2025-10-17 14:29 ` [PATCH bpf-next 5/5] selftests/bpf: remove test_tc_tunnel.sh Alexis Lothoré (eBPF Foundation)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2477894b-3325-4bc2-9d3c-a066b3cbb8f6@linux.dev \
--to=martin.lau@linux.dev \
--cc=alexis.lothore@bootlin.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bastien.curutchet@bootlin.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=ebpf@linuxfoundation.org \
--cc=eddyz87@gmail.com \
--cc=haoluo@google.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kpsingh@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=sdf@fomichev.me \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=thomas.petazzoni@bootlin.com \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox