public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
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


  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