On 12/20/24 11:55 AM, Amery Hung wrote:
+BTF_KFUNCS_START(qdisc_kfunc_ids) +BTF_ID_FLAGS(func, bpf_skb_get_hash, KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_kfree_skb, KF_RELEASE) +BTF_ID_FLAGS(func, bpf_qdisc_skb_drop, KF_RELEASE) +BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS) +BTF_KFUNCS_END(qdisc_kfunc_ids) + +BTF_SET_START(qdisc_common_kfunc_set) +BTF_ID(func, bpf_skb_get_hash) +BTF_ID(func, bpf_kfree_skb)
I think bpf_dynptr_from_skb should also be here.
+BTF_SET_END(qdisc_common_kfunc_set) + +BTF_SET_START(qdisc_enqueue_kfunc_set) +BTF_ID(func, bpf_qdisc_skb_drop) +BTF_SET_END(qdisc_enqueue_kfunc_set) + +static int bpf_qdisc_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id) +{ + if (bpf_Qdisc_ops.type != btf_type_by_id(prog->aux->attach_btf, + prog->aux->attach_btf_id)) + return 0; + + /* Skip the check when prog->attach_func_name is not yet available + * during check_cfg().
Instead of using attach_func_name, it is better to directly use the prog->expected_attach_type provided by the user space. It is essentially the member index of the "struct Qdisc_ops". Take a look at the prog_ops_moff() in bpf_tcp_ca.c.
+ */ + if (!btf_id_set8_contains(&qdisc_kfunc_ids, kfunc_id) || + !prog->aux->attach_func_name) + return 0; + + if (!strcmp(prog->aux->attach_func_name, "enqueue")) { + if (btf_id_set_contains(&qdisc_enqueue_kfunc_set, kfunc_id)) + return 0; + } + + return btf_id_set_contains(&qdisc_common_kfunc_set, kfunc_id) ? 0 : -EACCES; +}