Commit 26a7cf2b authored by Kui-Feng Lee's avatar Kui-Feng Lee Committed by Andrii Nakryiko

selftests/bpf: Ensure libbpf skip all-zeros fields of struct_ops maps.

A new version of a type may have additional fields that do not exist in
older versions. Previously, libbpf would reject struct_ops maps with a new
version containing extra fields when running on a machine with an old
kernel. However, we have updated libbpf to ignore these fields if their
values are all zeros or null in order to provide backward compatibility.
Signed-off-by: default avatarKui-Feng Lee <thinker.li@gmail.com>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20240313214139.685112-3-thinker.li@gmail.com
parent c911fc61
......@@ -93,9 +93,56 @@ static void test_struct_ops_load(void)
struct_ops_module__destroy(skel);
}
static void test_struct_ops_not_zeroed(void)
{
struct struct_ops_module *skel;
int err;
/* zeroed is 0, and zeroed_op is null */
skel = struct_ops_module__open();
if (!ASSERT_OK_PTR(skel, "struct_ops_module_open"))
return;
err = struct_ops_module__load(skel);
ASSERT_OK(err, "struct_ops_module_load");
struct_ops_module__destroy(skel);
/* zeroed is not 0 */
skel = struct_ops_module__open();
if (!ASSERT_OK_PTR(skel, "struct_ops_module_open_not_zeroed"))
return;
/* libbpf should reject the testmod_zeroed since struct
* bpf_testmod_ops in the kernel has no "zeroed" field and the
* value of "zeroed" is non-zero.
*/
skel->struct_ops.testmod_zeroed->zeroed = 0xdeadbeef;
err = struct_ops_module__load(skel);
ASSERT_ERR(err, "struct_ops_module_load_not_zeroed");
struct_ops_module__destroy(skel);
/* zeroed_op is not null */
skel = struct_ops_module__open();
if (!ASSERT_OK_PTR(skel, "struct_ops_module_open_not_zeroed_op"))
return;
/* libbpf should reject the testmod_zeroed since the value of its
* "zeroed_op" is not null.
*/
skel->struct_ops.testmod_zeroed->zeroed_op = skel->progs.test_3;
err = struct_ops_module__load(skel);
ASSERT_ERR(err, "struct_ops_module_load_not_zeroed_op");
struct_ops_module__destroy(skel);
}
void serial_test_struct_ops_module(void)
{
if (test__start_subtest("test_struct_ops_load"))
test_struct_ops_load();
if (test__start_subtest("test_struct_ops_not_zeroed"))
test_struct_ops_not_zeroed();
}
......@@ -23,7 +23,7 @@ void BPF_PROG(test_2, int a, int b)
test_2_result = a + b;
}
SEC("struct_ops/test_3")
SEC("?struct_ops/test_3")
int BPF_PROG(test_3, int a, int b)
{
test_2_result = a + b + 3;
......@@ -54,3 +54,17 @@ struct bpf_testmod_ops___v2 testmod_2 = {
.test_1 = (void *)test_1,
.test_2 = (void *)test_2_v2,
};
struct bpf_testmod_ops___zeroed {
int (*test_1)(void);
void (*test_2)(int a, int b);
int (*test_maybe_null)(int dummy, struct task_struct *task);
void (*zeroed_op)(int a, int b);
int zeroed;
};
SEC(".struct_ops.link")
struct bpf_testmod_ops___zeroed testmod_zeroed = {
.test_1 = (void *)test_1,
.test_2 = (void *)test_2_v2,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment