github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/testdata/kfunc.c (about) 1 #include "common.h" 2 3 char __license[] __section("license") = "Dual MIT/GPL"; 4 5 // CO-RE type compat checking doesn't allow matches between forward declarations 6 // and structs so we can't use forward declarations. Empty structs work just fine. 7 struct __sk_buff {}; 8 struct nf_conn {}; 9 struct bpf_sock_tuple {}; 10 struct bpf_ct_opts {}; 11 struct bpf_cpumask {}; 12 13 extern struct nf_conn *bpf_skb_ct_lookup(struct __sk_buff *, struct bpf_sock_tuple *, uint32_t, struct bpf_ct_opts *, uint32_t) __ksym; 14 extern void bpf_ct_release(struct nf_conn *) __ksym; 15 16 __section("tc") int call_kfunc(void *ctx) { 17 char buf[1]; 18 struct nf_conn *conn = bpf_skb_ct_lookup(ctx, (void *)buf, 0, (void *)buf, 0); 19 if (conn) { 20 bpf_ct_release(conn); 21 } 22 return 1; 23 } 24 25 extern int bpf_fentry_test1(int) __ksym; 26 27 __section("fentry/bpf_fentry_test2") int benchmark() { 28 // bpf_fentry_test1 is a valid kfunc but not allowed to be called from 29 // TC context. We use this to avoid loading a gajillion programs into 30 // the kernel when benchmarking the loader. 31 return bpf_fentry_test1(0); 32 } 33 34 extern void invalid_kfunc(void) __ksym __weak; 35 36 extern struct bpf_cpumask *bpf_cpumask_create(void) __ksym __weak; 37 extern void bpf_cpumask_release(struct bpf_cpumask *cpumask) __ksym __weak; 38 39 __section("tp_btf/task_newtask") int weak_kfunc_missing(void *ctx) { 40 if (bpf_ksym_exists(invalid_kfunc)) { 41 invalid_kfunc(); 42 return 0; 43 } 44 45 return 1; 46 } 47 48 __section("tp_btf/task_newtask") int call_weak_kfunc(void *ctx) { 49 if (bpf_ksym_exists(bpf_cpumask_create)) { 50 struct bpf_cpumask *mask = bpf_cpumask_create(); 51 if (mask) 52 bpf_cpumask_release(mask); 53 54 return 1; 55 } 56 57 return 0; 58 }