Skip to content

Commit

Permalink
selftests/bpf: Make seen_tc* variable tests more robust
Browse files Browse the repository at this point in the history
Martin reported that on his local dev machine the test_tc_chain_mixed() fails as
"test_tc_chain_mixed:FAIL:seen_tc5 unexpected seen_tc5: actual 1 != expected 0"
and others occasionally, too.

However, when running in a more isolated setup (qemu in particular), it works fine
for him. The reason is that there is a small race-window where seen_tc* could turn
into true for various test cases when there is background traffic, e.g. after the
asserts they often get reset. In such case when subsequent detach takes place,
unrelated background traffic could have already flipped the bool to true beforehand.

Add a small helper tc_skel_reset_all_seen() to reset all bools before we do the ping
test. At this point, everything is set up as expected and therefore no race can occur.
All tc_{opts,links} tests continue to pass after this change.

Reported-by: Martin KaFai Lau <martin.lau@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/r/20231006220655.1653-7-daniel@iogearbox.net
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
  • Loading branch information
borkmann authored and Martin KaFai Lau committed Oct 7, 2023
1 parent 685446b commit 37345b8
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 60 deletions.
5 changes: 5 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/tc_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,9 @@ static inline void assert_mprog_count_ifindex(int ifindex, int target, int expec
__assert_mprog_count(target, expected, ifindex);
}

static inline void tc_skel_reset_all_seen(struct test_tc_link *skel)
{
memset(skel->bss, 0, sizeof(*skel->bss));
}

#endif /* TC_HELPERS */
62 changes: 22 additions & 40 deletions tools/testing/selftests/bpf/prog_tests/tc_links.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ void serial_test_tc_links_basic(void)
ASSERT_EQ(optq.prog_ids[1], 0, "prog_ids[1]");
ASSERT_EQ(optq.link_ids[1], 0, "link_ids[1]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
Expand Down Expand Up @@ -97,6 +98,7 @@ void serial_test_tc_links_basic(void)
ASSERT_EQ(optq.prog_ids[1], 0, "prog_ids[1]");
ASSERT_EQ(optq.link_ids[1], 0, "link_ids[1]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
Expand Down Expand Up @@ -187,16 +189,14 @@ static void test_tc_links_before_target(int target)
ASSERT_EQ(optq.prog_ids[2], 0, "prog_ids[2]");
ASSERT_EQ(optq.link_ids[2], 0, "link_ids[2]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
ASSERT_EQ(skel->bss->seen_tc2, true, "seen_tc2");
ASSERT_EQ(skel->bss->seen_tc3, false, "seen_tc3");
ASSERT_EQ(skel->bss->seen_tc4, false, "seen_tc4");

skel->bss->seen_tc1 = false;
skel->bss->seen_tc2 = false;

LIBBPF_OPTS_RESET(optl,
.flags = BPF_F_BEFORE,
.relative_fd = bpf_program__fd(skel->progs.tc2),
Expand Down Expand Up @@ -246,6 +246,7 @@ static void test_tc_links_before_target(int target)
ASSERT_EQ(optq.prog_ids[4], 0, "prog_ids[4]");
ASSERT_EQ(optq.link_ids[4], 0, "link_ids[4]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
Expand Down Expand Up @@ -342,16 +343,14 @@ static void test_tc_links_after_target(int target)
ASSERT_EQ(optq.prog_ids[2], 0, "prog_ids[2]");
ASSERT_EQ(optq.link_ids[2], 0, "link_ids[2]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
ASSERT_EQ(skel->bss->seen_tc2, true, "seen_tc2");
ASSERT_EQ(skel->bss->seen_tc3, false, "seen_tc3");
ASSERT_EQ(skel->bss->seen_tc4, false, "seen_tc4");

skel->bss->seen_tc1 = false;
skel->bss->seen_tc2 = false;

LIBBPF_OPTS_RESET(optl,
.flags = BPF_F_AFTER,
.relative_fd = bpf_program__fd(skel->progs.tc1),
Expand Down Expand Up @@ -401,6 +400,7 @@ static void test_tc_links_after_target(int target)
ASSERT_EQ(optq.prog_ids[4], 0, "prog_ids[4]");
ASSERT_EQ(optq.link_ids[4], 0, "link_ids[4]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
Expand Down Expand Up @@ -502,6 +502,7 @@ static void test_tc_links_revision_target(int target)
ASSERT_EQ(optq.prog_ids[2], 0, "prog_ids[2]");
ASSERT_EQ(optq.link_ids[2], 0, "prog_ids[2]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
Expand Down Expand Up @@ -581,22 +582,20 @@ static void test_tc_chain_classic(int target, bool chain_tc_old)

assert_mprog_count(target, 2);

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
ASSERT_EQ(skel->bss->seen_tc2, true, "seen_tc2");
ASSERT_EQ(skel->bss->seen_tc3, chain_tc_old, "seen_tc3");

skel->bss->seen_tc1 = false;
skel->bss->seen_tc2 = false;
skel->bss->seen_tc3 = false;

err = bpf_link__detach(skel->links.tc2);
if (!ASSERT_OK(err, "prog_detach"))
goto cleanup;

assert_mprog_count(target, 1);

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
Expand Down Expand Up @@ -707,16 +706,13 @@ static void test_tc_links_replace_target(int target)
ASSERT_EQ(optq.prog_ids[2], 0, "prog_ids[2]");
ASSERT_EQ(optq.link_ids[2], 0, "link_ids[2]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
ASSERT_EQ(skel->bss->seen_tc2, true, "seen_tc2");
ASSERT_EQ(skel->bss->seen_tc3, false, "seen_tc3");

skel->bss->seen_tc1 = false;
skel->bss->seen_tc2 = false;
skel->bss->seen_tc3 = false;

LIBBPF_OPTS_RESET(optl,
.flags = BPF_F_REPLACE,
.relative_fd = bpf_program__fd(skel->progs.tc2),
Expand Down Expand Up @@ -781,16 +777,13 @@ static void test_tc_links_replace_target(int target)
ASSERT_EQ(optq.prog_ids[2], 0, "prog_ids[2]");
ASSERT_EQ(optq.link_ids[2], 0, "link_ids[2]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
ASSERT_EQ(skel->bss->seen_tc2, false, "seen_tc2");
ASSERT_EQ(skel->bss->seen_tc3, true, "seen_tc3");

skel->bss->seen_tc1 = false;
skel->bss->seen_tc2 = false;
skel->bss->seen_tc3 = false;

err = bpf_link__detach(skel->links.tc2);
if (!ASSERT_OK(err, "link_detach"))
goto cleanup;
Expand All @@ -812,16 +805,13 @@ static void test_tc_links_replace_target(int target)
ASSERT_EQ(optq.prog_ids[1], 0, "prog_ids[1]");
ASSERT_EQ(optq.link_ids[1], 0, "link_ids[1]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
ASSERT_EQ(skel->bss->seen_tc2, false, "seen_tc2");
ASSERT_EQ(skel->bss->seen_tc3, false, "seen_tc3");

skel->bss->seen_tc1 = false;
skel->bss->seen_tc2 = false;
skel->bss->seen_tc3 = false;

err = bpf_link__update_program(skel->links.tc1, skel->progs.tc1);
if (!ASSERT_OK(err, "link_update_self"))
goto cleanup;
Expand All @@ -843,6 +833,7 @@ static void test_tc_links_replace_target(int target)
ASSERT_EQ(optq.prog_ids[1], 0, "prog_ids[1]");
ASSERT_EQ(optq.link_ids[1], 0, "link_ids[1]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
Expand Down Expand Up @@ -1254,16 +1245,14 @@ static void test_tc_links_prepend_target(int target)
ASSERT_EQ(optq.prog_ids[2], 0, "prog_ids[2]");
ASSERT_EQ(optq.link_ids[2], 0, "link_ids[2]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
ASSERT_EQ(skel->bss->seen_tc2, true, "seen_tc2");
ASSERT_EQ(skel->bss->seen_tc3, false, "seen_tc3");
ASSERT_EQ(skel->bss->seen_tc4, false, "seen_tc4");

skel->bss->seen_tc1 = false;
skel->bss->seen_tc2 = false;

LIBBPF_OPTS_RESET(optl,
.flags = BPF_F_BEFORE,
);
Expand Down Expand Up @@ -1311,6 +1300,7 @@ static void test_tc_links_prepend_target(int target)
ASSERT_EQ(optq.prog_ids[4], 0, "prog_ids[4]");
ASSERT_EQ(optq.link_ids[4], 0, "link_ids[4]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
Expand Down Expand Up @@ -1411,16 +1401,14 @@ static void test_tc_links_append_target(int target)
ASSERT_EQ(optq.prog_ids[2], 0, "prog_ids[2]");
ASSERT_EQ(optq.link_ids[2], 0, "link_ids[2]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
ASSERT_EQ(skel->bss->seen_tc2, true, "seen_tc2");
ASSERT_EQ(skel->bss->seen_tc3, false, "seen_tc3");
ASSERT_EQ(skel->bss->seen_tc4, false, "seen_tc4");

skel->bss->seen_tc1 = false;
skel->bss->seen_tc2 = false;

LIBBPF_OPTS_RESET(optl,
.flags = BPF_F_AFTER,
);
Expand Down Expand Up @@ -1468,6 +1456,7 @@ static void test_tc_links_append_target(int target)
ASSERT_EQ(optq.prog_ids[4], 0, "prog_ids[4]");
ASSERT_EQ(optq.link_ids[4], 0, "link_ids[4]");

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
Expand Down Expand Up @@ -1637,38 +1626,33 @@ static void test_tc_chain_mixed(int target)

assert_mprog_count(target, 1);

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc4, false, "seen_tc4");
ASSERT_EQ(skel->bss->seen_tc5, false, "seen_tc5");
ASSERT_EQ(skel->bss->seen_tc6, true, "seen_tc6");

skel->bss->seen_tc4 = false;
skel->bss->seen_tc5 = false;
skel->bss->seen_tc6 = false;

err = bpf_link__update_program(skel->links.tc6, skel->progs.tc4);
if (!ASSERT_OK(err, "link_update"))
goto cleanup;

assert_mprog_count(target, 1);

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc4, true, "seen_tc4");
ASSERT_EQ(skel->bss->seen_tc5, true, "seen_tc5");
ASSERT_EQ(skel->bss->seen_tc6, false, "seen_tc6");

skel->bss->seen_tc4 = false;
skel->bss->seen_tc5 = false;
skel->bss->seen_tc6 = false;

err = bpf_link__detach(skel->links.tc6);
if (!ASSERT_OK(err, "prog_detach"))
goto cleanup;

assert_mprog_count(target, 0);

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc4, false, "seen_tc4");
Expand Down Expand Up @@ -1758,22 +1742,20 @@ static void test_tc_links_ingress(int target, bool chain_tc_old,

assert_mprog_count(target, 2);

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
ASSERT_EQ(skel->bss->seen_tc2, true, "seen_tc2");
ASSERT_EQ(skel->bss->seen_tc3, chain_tc_old, "seen_tc3");

skel->bss->seen_tc1 = false;
skel->bss->seen_tc2 = false;
skel->bss->seen_tc3 = false;

err = bpf_link__detach(skel->links.tc2);
if (!ASSERT_OK(err, "prog_detach"))
goto cleanup;

assert_mprog_count(target, 1);

tc_skel_reset_all_seen(skel);
ASSERT_OK(system(ping_cmd), ping_cmd);

ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
Expand Down
Loading

0 comments on commit 37345b8

Please sign in to comment.