Merge branch 'selftests-bpf-tc_links-tc_opts-unserialize-tests'

Bastien Curutchet says:

====================
Both tc_links.c and tc_opts.c do their tests on the loopback interface.
It prevents from parallelizing their executions.

Add a new behaviour to the test_progs framework that creates and opens a
new network namespace to run a test in it. This is done automatically on
tests whose names start with 'ns_'.

One test already has a name starting with 'ns_', so PATCH 1 renames it
to avoid conflicts. PATCH 2 introduces the test_progs 'feature'.
PATCH 3 & 4 convert some tests to use these dedicated namespaces.

Signed-off-by: Bastien Curutchet (eBPF Foundation) <bastien.curutchet@bootlin.com>

Changes in v2:
 - Handle the netns creation / opening directly in test_progs
 - Link to v1: https://lore.kernel.org/bpf/e3838d93-04e3-4e96-af53-e9e63550d7ba@bootlin.com
====================

Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250219-b4-tc_links-v2-0-14504db136b7@bootlin.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Alexei Starovoitov 2025-02-19 09:46:02 -08:00
commit d0da259de5
4 changed files with 64 additions and 65 deletions

View File

@ -200,41 +200,28 @@ static void test_ns_current_pid_tgid_new_ns(int (*fn)(void *), void *arg)
return;
}
static void test_in_netns(int (*fn)(void *), void *arg)
{
struct nstoken *nstoken = NULL;
SYS(cleanup, "ip netns add ns_current_pid_tgid");
SYS(cleanup, "ip -net ns_current_pid_tgid link set dev lo up");
nstoken = open_netns("ns_current_pid_tgid");
if (!ASSERT_OK_PTR(nstoken, "open_netns"))
goto cleanup;
test_ns_current_pid_tgid_new_ns(fn, arg);
cleanup:
if (nstoken)
close_netns(nstoken);
SYS_NOFAIL("ip netns del ns_current_pid_tgid");
}
/* TODO: use a different tracepoint */
void serial_test_ns_current_pid_tgid(void)
void serial_test_current_pid_tgid(void)
{
if (test__start_subtest("root_ns_tp"))
test_current_pid_tgid_tp(NULL);
if (test__start_subtest("new_ns_tp"))
test_ns_current_pid_tgid_new_ns(test_current_pid_tgid_tp, NULL);
if (test__start_subtest("new_ns_cgrp")) {
int cgroup_fd = -1;
cgroup_fd = test__join_cgroup("/sock_addr");
if (ASSERT_GE(cgroup_fd, 0, "join_cgroup")) {
test_in_netns(test_current_pid_tgid_cgrp, &cgroup_fd);
close(cgroup_fd);
}
}
if (test__start_subtest("new_ns_sk_msg"))
test_in_netns(test_current_pid_tgid_sk_msg, NULL);
}
void test_ns_current_pid_tgid_cgrp(void)
{
int cgroup_fd = test__join_cgroup("/sock_addr");
if (ASSERT_OK_FD(cgroup_fd, "join_cgroup")) {
test_ns_current_pid_tgid_new_ns(test_current_pid_tgid_cgrp, &cgroup_fd);
close(cgroup_fd);
}
}
void test_ns_current_pid_tgid_sk_msg(void)
{
test_ns_current_pid_tgid_new_ns(test_current_pid_tgid_sk_msg, NULL);
}

View File

@ -13,7 +13,7 @@
#include "netlink_helpers.h"
#include "tc_helpers.h"
void serial_test_tc_links_basic(void)
void test_ns_tc_links_basic(void)
{
LIBBPF_OPTS(bpf_prog_query_opts, optq);
LIBBPF_OPTS(bpf_tcx_opts, optl);
@ -260,7 +260,7 @@ static void test_tc_links_before_target(int target)
assert_mprog_count(target, 0);
}
void serial_test_tc_links_before(void)
void test_ns_tc_links_before(void)
{
test_tc_links_before_target(BPF_TCX_INGRESS);
test_tc_links_before_target(BPF_TCX_EGRESS);
@ -414,7 +414,7 @@ static void test_tc_links_after_target(int target)
assert_mprog_count(target, 0);
}
void serial_test_tc_links_after(void)
void test_ns_tc_links_after(void)
{
test_tc_links_after_target(BPF_TCX_INGRESS);
test_tc_links_after_target(BPF_TCX_EGRESS);
@ -514,7 +514,7 @@ static void test_tc_links_revision_target(int target)
assert_mprog_count(target, 0);
}
void serial_test_tc_links_revision(void)
void test_ns_tc_links_revision(void)
{
test_tc_links_revision_target(BPF_TCX_INGRESS);
test_tc_links_revision_target(BPF_TCX_EGRESS);
@ -618,7 +618,7 @@ static void test_tc_chain_classic(int target, bool chain_tc_old)
assert_mprog_count(target, 0);
}
void serial_test_tc_links_chain_classic(void)
void test_ns_tc_links_chain_classic(void)
{
test_tc_chain_classic(BPF_TCX_INGRESS, false);
test_tc_chain_classic(BPF_TCX_EGRESS, false);
@ -846,7 +846,7 @@ static void test_tc_links_replace_target(int target)
assert_mprog_count(target, 0);
}
void serial_test_tc_links_replace(void)
void test_ns_tc_links_replace(void)
{
test_tc_links_replace_target(BPF_TCX_INGRESS);
test_tc_links_replace_target(BPF_TCX_EGRESS);
@ -1158,7 +1158,7 @@ static void test_tc_links_invalid_target(int target)
assert_mprog_count(target, 0);
}
void serial_test_tc_links_invalid(void)
void test_ns_tc_links_invalid(void)
{
test_tc_links_invalid_target(BPF_TCX_INGRESS);
test_tc_links_invalid_target(BPF_TCX_EGRESS);
@ -1314,7 +1314,7 @@ static void test_tc_links_prepend_target(int target)
assert_mprog_count(target, 0);
}
void serial_test_tc_links_prepend(void)
void test_ns_tc_links_prepend(void)
{
test_tc_links_prepend_target(BPF_TCX_INGRESS);
test_tc_links_prepend_target(BPF_TCX_EGRESS);
@ -1470,7 +1470,7 @@ static void test_tc_links_append_target(int target)
assert_mprog_count(target, 0);
}
void serial_test_tc_links_append(void)
void test_ns_tc_links_append(void)
{
test_tc_links_append_target(BPF_TCX_INGRESS);
test_tc_links_append_target(BPF_TCX_EGRESS);
@ -1568,7 +1568,7 @@ static void test_tc_links_dev_cleanup_target(int target)
ASSERT_EQ(if_nametoindex("tcx_opts2"), 0, "dev2_removed");
}
void serial_test_tc_links_dev_cleanup(void)
void test_ns_tc_links_dev_cleanup(void)
{
test_tc_links_dev_cleanup_target(BPF_TCX_INGRESS);
test_tc_links_dev_cleanup_target(BPF_TCX_EGRESS);
@ -1672,7 +1672,7 @@ static void test_tc_chain_mixed(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_links_chain_mixed(void)
void test_ns_tc_links_chain_mixed(void)
{
test_tc_chain_mixed(BPF_TCX_INGRESS);
test_tc_chain_mixed(BPF_TCX_EGRESS);
@ -1782,7 +1782,7 @@ static void test_tc_links_ingress(int target, bool chain_tc_old,
assert_mprog_count(target, 0);
}
void serial_test_tc_links_ingress(void)
void test_ns_tc_links_ingress(void)
{
test_tc_links_ingress(BPF_TCX_INGRESS, true, true);
test_tc_links_ingress(BPF_TCX_INGRESS, true, false);
@ -1823,7 +1823,7 @@ static int qdisc_replace(int ifindex, const char *kind, bool block)
return err;
}
void serial_test_tc_links_dev_chain0(void)
void test_ns_tc_links_dev_chain0(void)
{
int err, ifindex;
@ -1955,7 +1955,7 @@ static void test_tc_links_dev_mixed(int target)
ASSERT_EQ(if_nametoindex("tcx_opts2"), 0, "dev2_removed");
}
void serial_test_tc_links_dev_mixed(void)
void test_ns_tc_links_dev_mixed(void)
{
test_tc_links_dev_mixed(BPF_TCX_INGRESS);
test_tc_links_dev_mixed(BPF_TCX_EGRESS);

View File

@ -10,7 +10,7 @@
#include "test_tc_link.skel.h"
#include "tc_helpers.h"
void serial_test_tc_opts_basic(void)
void test_ns_tc_opts_basic(void)
{
LIBBPF_OPTS(bpf_prog_attach_opts, opta);
LIBBPF_OPTS(bpf_prog_detach_opts, optd);
@ -254,7 +254,7 @@ static void test_tc_opts_before_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_before(void)
void test_ns_tc_opts_before(void)
{
test_tc_opts_before_target(BPF_TCX_INGRESS);
test_tc_opts_before_target(BPF_TCX_EGRESS);
@ -445,7 +445,7 @@ static void test_tc_opts_after_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_after(void)
void test_ns_tc_opts_after(void)
{
test_tc_opts_after_target(BPF_TCX_INGRESS);
test_tc_opts_after_target(BPF_TCX_EGRESS);
@ -554,7 +554,7 @@ static void test_tc_opts_revision_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_revision(void)
void test_ns_tc_opts_revision(void)
{
test_tc_opts_revision_target(BPF_TCX_INGRESS);
test_tc_opts_revision_target(BPF_TCX_EGRESS);
@ -655,7 +655,7 @@ static void test_tc_chain_classic(int target, bool chain_tc_old)
assert_mprog_count(target, 0);
}
void serial_test_tc_opts_chain_classic(void)
void test_ns_tc_opts_chain_classic(void)
{
test_tc_chain_classic(BPF_TCX_INGRESS, false);
test_tc_chain_classic(BPF_TCX_EGRESS, false);
@ -864,7 +864,7 @@ static void test_tc_opts_replace_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_replace(void)
void test_ns_tc_opts_replace(void)
{
test_tc_opts_replace_target(BPF_TCX_INGRESS);
test_tc_opts_replace_target(BPF_TCX_EGRESS);
@ -1017,7 +1017,7 @@ static void test_tc_opts_invalid_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_invalid(void)
void test_ns_tc_opts_invalid(void)
{
test_tc_opts_invalid_target(BPF_TCX_INGRESS);
test_tc_opts_invalid_target(BPF_TCX_EGRESS);
@ -1157,7 +1157,7 @@ static void test_tc_opts_prepend_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_prepend(void)
void test_ns_tc_opts_prepend(void)
{
test_tc_opts_prepend_target(BPF_TCX_INGRESS);
test_tc_opts_prepend_target(BPF_TCX_EGRESS);
@ -1297,7 +1297,7 @@ static void test_tc_opts_append_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_append(void)
void test_ns_tc_opts_append(void)
{
test_tc_opts_append_target(BPF_TCX_INGRESS);
test_tc_opts_append_target(BPF_TCX_EGRESS);
@ -1387,7 +1387,7 @@ static void test_tc_opts_dev_cleanup_target(int target)
ASSERT_EQ(if_nametoindex("tcx_opts2"), 0, "dev2_removed");
}
void serial_test_tc_opts_dev_cleanup(void)
void test_ns_tc_opts_dev_cleanup(void)
{
test_tc_opts_dev_cleanup_target(BPF_TCX_INGRESS);
test_tc_opts_dev_cleanup_target(BPF_TCX_EGRESS);
@ -1563,7 +1563,7 @@ static void test_tc_opts_mixed_target(int target)
assert_mprog_count(target, 0);
}
void serial_test_tc_opts_mixed(void)
void test_ns_tc_opts_mixed(void)
{
test_tc_opts_mixed_target(BPF_TCX_INGRESS);
test_tc_opts_mixed_target(BPF_TCX_EGRESS);
@ -1642,7 +1642,7 @@ static void test_tc_opts_demixed_target(int target)
assert_mprog_count(target, 0);
}
void serial_test_tc_opts_demixed(void)
void test_ns_tc_opts_demixed(void)
{
test_tc_opts_demixed_target(BPF_TCX_INGRESS);
test_tc_opts_demixed_target(BPF_TCX_EGRESS);
@ -1813,7 +1813,7 @@ static void test_tc_opts_detach_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_detach(void)
void test_ns_tc_opts_detach(void)
{
test_tc_opts_detach_target(BPF_TCX_INGRESS);
test_tc_opts_detach_target(BPF_TCX_EGRESS);
@ -2020,7 +2020,7 @@ static void test_tc_opts_detach_before_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_detach_before(void)
void test_ns_tc_opts_detach_before(void)
{
test_tc_opts_detach_before_target(BPF_TCX_INGRESS);
test_tc_opts_detach_before_target(BPF_TCX_EGRESS);
@ -2236,7 +2236,7 @@ static void test_tc_opts_detach_after_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_detach_after(void)
void test_ns_tc_opts_detach_after(void)
{
test_tc_opts_detach_after_target(BPF_TCX_INGRESS);
test_tc_opts_detach_after_target(BPF_TCX_EGRESS);
@ -2265,7 +2265,7 @@ static void test_tc_opts_delete_empty(int target, bool chain_tc_old)
assert_mprog_count(target, 0);
}
void serial_test_tc_opts_delete_empty(void)
void test_ns_tc_opts_delete_empty(void)
{
test_tc_opts_delete_empty(BPF_TCX_INGRESS, false);
test_tc_opts_delete_empty(BPF_TCX_EGRESS, false);
@ -2372,7 +2372,7 @@ static void test_tc_chain_mixed(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_chain_mixed(void)
void test_ns_tc_opts_chain_mixed(void)
{
test_tc_chain_mixed(BPF_TCX_INGRESS);
test_tc_chain_mixed(BPF_TCX_EGRESS);
@ -2446,7 +2446,7 @@ static void test_tc_opts_max_target(int target, int flags, bool relative)
ASSERT_EQ(if_nametoindex("tcx_opts2"), 0, "dev2_removed");
}
void serial_test_tc_opts_max(void)
void test_ns_tc_opts_max(void)
{
test_tc_opts_max_target(BPF_TCX_INGRESS, 0, false);
test_tc_opts_max_target(BPF_TCX_EGRESS, 0, false);
@ -2748,7 +2748,7 @@ static void test_tc_opts_query_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_query(void)
void test_ns_tc_opts_query(void)
{
test_tc_opts_query_target(BPF_TCX_INGRESS);
test_tc_opts_query_target(BPF_TCX_EGRESS);
@ -2807,7 +2807,7 @@ static void test_tc_opts_query_attach_target(int target)
test_tc_link__destroy(skel);
}
void serial_test_tc_opts_query_attach(void)
void test_ns_tc_opts_query_attach(void)
{
test_tc_opts_query_attach_target(BPF_TCX_INGRESS);
test_tc_opts_query_attach_target(BPF_TCX_EGRESS);

View File

@ -1365,10 +1365,19 @@ static int recv_message(int sock, struct msg *msg)
return ret;
}
static bool ns_is_needed(const char *test_name)
{
if (strlen(test_name) < 3)
return false;
return !strncmp(test_name, "ns_", 3);
}
static void run_one_test(int test_num)
{
struct prog_test_def *test = &prog_test_defs[test_num];
struct test_state *state = &test_states[test_num];
struct netns_obj *ns = NULL;
env.test = test;
env.test_state = state;
@ -1376,10 +1385,13 @@ static void run_one_test(int test_num)
stdio_hijack(&state->log_buf, &state->log_cnt);
watchdog_start();
if (ns_is_needed(test->test_name))
ns = netns_new(test->test_name, true);
if (test->run_test)
test->run_test();
else if (test->run_serial_test)
test->run_serial_test();
netns_free(ns);
watchdog_stop();
/* ensure last sub-test is finalized properly */