1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2022 Benjamin Tissoires */ 3 4 #include ".output/vmlinux.h" 5 #include <bpf/bpf_helpers.h> 6 #include <bpf/bpf_tracing.h> 7 8 #define HID_BPF_MAX_PROGS 1024 9 10 extern bool call_hid_bpf_prog_release(u64 prog, int table_cnt) __ksym; 11 12 struct { 13 __uint(type, BPF_MAP_TYPE_PROG_ARRAY); 14 __uint(max_entries, HID_BPF_MAX_PROGS); 15 __uint(key_size, sizeof(__u32)); 16 __uint(value_size, sizeof(__u32)); 17 } hid_jmp_table SEC(".maps"); 18 19 struct { 20 __uint(type, BPF_MAP_TYPE_HASH); 21 __uint(max_entries, HID_BPF_MAX_PROGS * HID_BPF_PROG_TYPE_MAX); 22 __type(key, void *); 23 __type(value, __u8); 24 } progs_map SEC(".maps"); 25 26 SEC("fmod_ret/__hid_bpf_tail_call") 27 int BPF_PROG(hid_tail_call, struct hid_bpf_ctx *hctx) 28 { 29 bpf_tail_call(ctx, &hid_jmp_table, hctx->index); 30 31 return 0; 32 } 33 34 static void release_prog(u64 prog) 35 { 36 u8 *value; 37 38 value = bpf_map_lookup_elem(&progs_map, &prog); 39 if (!value) 40 return; 41 42 if (call_hid_bpf_prog_release(prog, *value)) 43 bpf_map_delete_elem(&progs_map, &prog); 44 } 45 46 SEC("fexit/bpf_prog_release") 47 int BPF_PROG(hid_prog_release, struct inode *inode, struct file *filp) 48 { 49 u64 prog = (u64)filp->private_data; 50 51 release_prog(prog); 52 53 return 0; 54 } 55 56 SEC("fexit/bpf_free_inode") 57 int BPF_PROG(hid_free_inode, struct inode *inode) 58 { 59 u64 prog = (u64)inode->i_private; 60 61 release_prog(prog); 62 63 return 0; 64 } 65 66 char LICENSE[] SEC("license") = "GPL"; 67