-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'bpf: Implement two type cast kfuncs'
Yonghong Song says: ==================== Currenty, a non-tracing bpf program typically has a single 'context' argument with predefined uapi struct type. Following these uapi struct, user is able to access other fields defined in uapi header. Inside the kernel, the user-seen 'context' argument is replaced with 'kernel context' (or 'kctx' in short) which can access more information than what uapi header provides. To access other info not in uapi header, people typically do two things: (1). extend uapi to access more fields rooted from 'context'. (2). use bpf_probe_read_kernl() helper to read particular field based on kctx. Using (1) needs uapi change and using (2) makes code more complex since direct memory access is not allowed. There are already a few instances trying to access more information from kctx: . trying to access some fields from perf_event kctx ([1]). . trying to access some fields from xdp kctx ([2]). This patch set tried to allow direct memory access for kctx fields by introducing bpf_cast_to_kern_ctx() kfunc. Martin mentioned a use case like type casting below: #define skb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB))) basically a 'unsigned char *" casted to 'struct skb_shared_info *'. This patch set tries to support such a use case as well with bpf_rdonly_cast(). For the patch series, Patch 1 added support for a kfunc available to all prog types. Patch 2 added bpf_cast_to_kern_ctx() kfunc. Patch 3 added bpf_rdonly_cast() kfunc. Patch 4 added a few positive and negative tests. [1] https://lore.kernel.org/bpf/ad15b398-9069-4a0e-48cb-4bb651ec3088@meta.com/ [2] https://lore.kernel.org/bpf/20221109215242.1279993-1-john.fastabend@gmail.com/ Changelog: v3 -> v4: - remove unnecessary bpf_ctx_convert.t error checking - add and use meta.ret_btf_id instead of meta.arg_constant.value for bpf_cast_to_kern_ctx(). - add PTR_TRUSTED to the return PTR_TO_BTF_ID type for bpf_cast_to_kern_ctx(). v2 -> v3: - rebase on top of bpf-next (for merging conflicts) - add the selftest to s390x deny list rfcv1 -> v2: - break original one kfunc into two. - add missing error checks and error logs. - adapt to the new conventions in https://lore.kernel.org/all/20221118015614.2013203-1-memxor@gmail.com/ for example, with __ign and __k suffix. - added support in fixup_kfunc_call() to replace kfunc calls with a single mov. ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
- Loading branch information
Showing
7 changed files
with
293 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ | ||
#include <test_progs.h> | ||
#include <network_helpers.h> | ||
#include "type_cast.skel.h" | ||
|
||
static void test_xdp(void) | ||
{ | ||
struct type_cast *skel; | ||
int err, prog_fd; | ||
char buf[128]; | ||
|
||
LIBBPF_OPTS(bpf_test_run_opts, topts, | ||
.data_in = &pkt_v4, | ||
.data_size_in = sizeof(pkt_v4), | ||
.data_out = buf, | ||
.data_size_out = sizeof(buf), | ||
.repeat = 1, | ||
); | ||
|
||
skel = type_cast__open(); | ||
if (!ASSERT_OK_PTR(skel, "skel_open")) | ||
return; | ||
|
||
bpf_program__set_autoload(skel->progs.md_xdp, true); | ||
err = type_cast__load(skel); | ||
if (!ASSERT_OK(err, "skel_load")) | ||
goto out; | ||
|
||
prog_fd = bpf_program__fd(skel->progs.md_xdp); | ||
err = bpf_prog_test_run_opts(prog_fd, &topts); | ||
ASSERT_OK(err, "test_run"); | ||
ASSERT_EQ(topts.retval, XDP_PASS, "xdp test_run retval"); | ||
|
||
ASSERT_EQ(skel->bss->ifindex, 1, "xdp_md ifindex"); | ||
ASSERT_EQ(skel->bss->ifindex, skel->bss->ingress_ifindex, "xdp_md ingress_ifindex"); | ||
ASSERT_STREQ(skel->bss->name, "lo", "xdp_md name"); | ||
ASSERT_NEQ(skel->bss->inum, 0, "xdp_md inum"); | ||
|
||
out: | ||
type_cast__destroy(skel); | ||
} | ||
|
||
static void test_tc(void) | ||
{ | ||
struct type_cast *skel; | ||
int err, prog_fd; | ||
|
||
LIBBPF_OPTS(bpf_test_run_opts, topts, | ||
.data_in = &pkt_v4, | ||
.data_size_in = sizeof(pkt_v4), | ||
.repeat = 1, | ||
); | ||
|
||
skel = type_cast__open(); | ||
if (!ASSERT_OK_PTR(skel, "skel_open")) | ||
return; | ||
|
||
bpf_program__set_autoload(skel->progs.md_skb, true); | ||
err = type_cast__load(skel); | ||
if (!ASSERT_OK(err, "skel_load")) | ||
goto out; | ||
|
||
prog_fd = bpf_program__fd(skel->progs.md_skb); | ||
err = bpf_prog_test_run_opts(prog_fd, &topts); | ||
ASSERT_OK(err, "test_run"); | ||
ASSERT_EQ(topts.retval, 0, "tc test_run retval"); | ||
|
||
ASSERT_EQ(skel->bss->meta_len, 0, "skb meta_len"); | ||
ASSERT_EQ(skel->bss->frag0_len, 0, "skb frag0_len"); | ||
ASSERT_NEQ(skel->bss->kskb_len, 0, "skb len"); | ||
ASSERT_NEQ(skel->bss->kskb2_len, 0, "skb2 len"); | ||
ASSERT_EQ(skel->bss->kskb_len, skel->bss->kskb2_len, "skb len compare"); | ||
|
||
out: | ||
type_cast__destroy(skel); | ||
} | ||
|
||
static const char * const negative_tests[] = { | ||
"untrusted_ptr", | ||
"kctx_u64", | ||
}; | ||
|
||
static void test_negative(void) | ||
{ | ||
struct bpf_program *prog; | ||
struct type_cast *skel; | ||
int i, err; | ||
|
||
for (i = 0; i < ARRAY_SIZE(negative_tests); i++) { | ||
skel = type_cast__open(); | ||
if (!ASSERT_OK_PTR(skel, "skel_open")) | ||
return; | ||
|
||
prog = bpf_object__find_program_by_name(skel->obj, negative_tests[i]); | ||
if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) | ||
goto out; | ||
bpf_program__set_autoload(prog, true); | ||
err = type_cast__load(skel); | ||
ASSERT_ERR(err, "skel_load"); | ||
out: | ||
type_cast__destroy(skel); | ||
} | ||
} | ||
|
||
void test_type_cast(void) | ||
{ | ||
if (test__start_subtest("xdp")) | ||
test_xdp(); | ||
if (test__start_subtest("tc")) | ||
test_tc(); | ||
if (test__start_subtest("negative")) | ||
test_negative(); | ||
} |
Oops, something went wrong.