aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin KaFai Lau <martin.lau@kernel.org>2024-02-01 12:17:41 -0800
committerMartin KaFai Lau <martin.lau@kernel.org>2024-02-01 17:42:45 -0800
commitb7b01e38000843a94c00ccfd40251e6b459408b7 (patch)
tree917e8c047a931e6fda90f8ac5e71b97964d1a56c
parent943b043aeecce9accb6d367af47791c633e95e4d (diff)
downloadbpf-next-qdisc-ideas.tar.gz
bpf: Trying out ideas for qdiscqdisc-ideas
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
-rw-r--r--tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c31
-rw-r--r--tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h6
-rw-r--r--tools/testing/selftests/bpf/progs/struct_ops_module.c16
3 files changed, 53 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
index 4754c662b39ff..7cecd221febde 100644
--- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
@@ -522,6 +522,27 @@ BTF_ID_FLAGS(func, bpf_kfunc_call_test_static_unused_arg)
BTF_ID_FLAGS(func, bpf_kfunc_call_test_offset)
BTF_KFUNCS_END(bpf_testmod_check_kfunc_ids)
+struct bpf_sk_buff_ptr {
+ struct sk_buff *skb;
+};
+
+BTF_ID_LIST_SINGLE(bpf_sk_buff_ptr_ids, struct, bpf_sk_buff_ptr)
+
+__bpf_kfunc int bpf_qdisc_drop(struct sk_buff *skb, struct Qdisc *sch,
+ struct bpf_sk_buff_ptr *to_free_list)
+{
+ return 1; /* NET_XMIT_DROP */
+}
+
+BTF_KFUNCS_START(bpf_testmod_ops_kfunc_ids)
+BTF_ID_FLAGS(func, bpf_qdisc_drop, KF_RELEASE)
+BTF_KFUNCS_END(bpf_testmod_ops_kfunc_ids)
+
+static const struct btf_kfunc_id_set bpf_testmod_ops_kfunc_set = {
+ .owner = THIS_MODULE,
+ .set = &bpf_testmod_ops_kfunc_ids,
+};
+
static int bpf_testmod_ops_init(struct btf *btf)
{
return 0;
@@ -532,6 +553,15 @@ static bool bpf_testmod_ops_is_valid_access(int off, int size,
const struct bpf_prog *prog,
struct bpf_insn_access_aux *info)
{
+ if (!strcmp(prog->aux->attach_func_name, "enqueue") &&
+ /* FIXME, use get_ctx_arg_idx instead */
+ off / sizeof(__u64) == 2) {
+ info->reg_type = PTR_TO_BTF_ID | PTR_TRUSTED;
+ info->btf = prog->aux->attach_btf;
+ info->btf_id = bpf_sk_buff_ptr_ids[0];
+ return true;
+ }
+
return bpf_tracing_btf_ctx_access(off, size, type, prog, info);
}
@@ -601,6 +631,7 @@ static int bpf_testmod_init(void)
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_testmod_kfunc_set);
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_testmod_kfunc_set);
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &bpf_testmod_kfunc_set);
+ ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &bpf_testmod_ops_kfunc_set);
ret = ret ?: register_bpf_struct_ops(&bpf_bpf_testmod_ops, bpf_testmod_ops);
if (ret < 0)
return ret;
diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h
index ca5435751c794..888c2a19d6d06 100644
--- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h
+++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h
@@ -28,9 +28,15 @@ struct bpf_iter_testmod_seq {
int cnt;
};
+struct sk_buff;
+struct Qdisc;
struct bpf_testmod_ops {
int (*test_1)(void);
int (*test_2)(int a, int b);
+ int (*enqueue)(struct sk_buff *skb,
+ struct Qdisc *sch,
+ struct sk_buff **to_free);
+ struct sk_buff * (*dequeue)(struct Qdisc *);
};
#endif /* _BPF_TESTMOD_H */
diff --git a/tools/testing/selftests/bpf/progs/struct_ops_module.c b/tools/testing/selftests/bpf/progs/struct_ops_module.c
index e44ac55195ca9..756ef668fdfa3 100644
--- a/tools/testing/selftests/bpf/progs/struct_ops_module.c
+++ b/tools/testing/selftests/bpf/progs/struct_ops_module.c
@@ -7,6 +7,12 @@
char _license[] SEC("license") = "GPL";
+struct bpf_sk_buff_ptr {
+ struct sk_buff *skb;
+};
+
+extern int bpf_qdisc_drop(struct sk_buff *skb, struct Qdisc *sch,
+ struct bpf_sk_buff_ptr *skb_ptr) __ksym;
int test_2_result = 0;
SEC("struct_ops/test_1")
@@ -22,9 +28,19 @@ int BPF_PROG(test_2, int a, int b)
return a + b;
}
+SEC("struct_ops/enqueue")
+int BPF_PROG(test_enqueue, struct sk_buff *skb,
+ struct Qdisc *sch,
+ struct bpf_sk_buff_ptr *to_free_list)
+{
+ /* This will fail to load due to KF_RELEASE in bpf_qdisc_drop */
+ return bpf_qdisc_drop(skb, sch, to_free_list);
+}
+
SEC(".struct_ops.link")
struct bpf_testmod_ops testmod_1 = {
.test_1 = (void *)test_1,
.test_2 = (void *)test_2,
+ .enqueue = (void *)test_enqueue,
};