selftests/bpf: validate nulled-out struct_ops program is handled properly

Add a selftests validating that it's possible to have some struct_ops
callback set declaratively, then disable it (by setting to NULL)
programmatically. Libbpf should detect that such program should
not be loaded. Otherwise, it will unnecessarily fail the loading
when the host kernel does not have the type information.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20240428030954.3918764-2-andrii@kernel.org
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
This commit is contained in:
Andrii Nakryiko
2024-04-27 20:09:54 -07:00
committed by Martin KaFai Lau
parent f973fccd43
commit 1bba3b3d37
2 changed files with 23 additions and 2 deletions

View File

@@ -66,6 +66,7 @@ static void test_struct_ops_load(void)
* auto-loading, or it will fail to load.
*/
bpf_program__set_autoload(skel->progs.test_2, false);
bpf_map__set_autocreate(skel->maps.testmod_zeroed, false);
err = struct_ops_module__load(skel);
if (!ASSERT_OK(err, "struct_ops_module_load"))
@@ -103,6 +104,10 @@ static void test_struct_ops_not_zeroed(void)
if (!ASSERT_OK_PTR(skel, "struct_ops_module_open"))
return;
skel->struct_ops.testmod_zeroed->zeroed = 0;
/* zeroed_op prog should be not loaded automatically now */
skel->struct_ops.testmod_zeroed->zeroed_op = NULL;
err = struct_ops_module__load(skel);
ASSERT_OK(err, "struct_ops_module_load");
@@ -118,6 +123,7 @@ static void test_struct_ops_not_zeroed(void)
* value of "zeroed" is non-zero.
*/
skel->struct_ops.testmod_zeroed->zeroed = 0xdeadbeef;
skel->struct_ops.testmod_zeroed->zeroed_op = NULL;
err = struct_ops_module__load(skel);
ASSERT_ERR(err, "struct_ops_module_load_not_zeroed");
@@ -148,15 +154,23 @@ static void test_struct_ops_incompatible(void)
{
struct struct_ops_module *skel;
struct bpf_link *link;
int err;
skel = struct_ops_module__open_and_load();
if (!ASSERT_OK_PTR(skel, "open_and_load"))
skel = struct_ops_module__open();
if (!ASSERT_OK_PTR(skel, "struct_ops_module_open"))
return;
bpf_map__set_autocreate(skel->maps.testmod_zeroed, false);
err = struct_ops_module__load(skel);
if (!ASSERT_OK(err, "skel_load"))
goto cleanup;
link = bpf_map__attach_struct_ops(skel->maps.testmod_incompatible);
if (ASSERT_OK_PTR(link, "attach_struct_ops"))
bpf_link__destroy(link);
cleanup:
struct_ops_module__destroy(skel);
}

View File

@@ -63,10 +63,17 @@ struct bpf_testmod_ops___zeroed {
int zeroed;
};
SEC("?struct_ops/test_3")
int BPF_PROG(zeroed_op)
{
return 1;
}
SEC(".struct_ops.link")
struct bpf_testmod_ops___zeroed testmod_zeroed = {
.test_1 = (void *)test_1,
.test_2 = (void *)test_2_v2,
.zeroed_op = (void *)zeroed_op,
};
struct bpf_testmod_ops___incompatible {