1*00899e7eSAlexei Starovoitov // SPDX-License-Identifier: GPL-2.0 2*00899e7eSAlexei Starovoitov /* Copyright (c) 2021 Facebook */ 3*00899e7eSAlexei Starovoitov #include <linux/stddef.h> 4*00899e7eSAlexei Starovoitov #include <linux/bpf.h> 5*00899e7eSAlexei Starovoitov #include <bpf/bpf_helpers.h> 6*00899e7eSAlexei Starovoitov #include <bpf/bpf_tracing.h> 7*00899e7eSAlexei Starovoitov #include <../../../tools/include/linux/filter.h> 8*00899e7eSAlexei Starovoitov 9*00899e7eSAlexei Starovoitov char _license[] SEC("license") = "GPL"; 10*00899e7eSAlexei Starovoitov 11*00899e7eSAlexei Starovoitov struct args { 12*00899e7eSAlexei Starovoitov __u64 log_buf; 13*00899e7eSAlexei Starovoitov __u32 log_size; 14*00899e7eSAlexei Starovoitov int max_entries; 15*00899e7eSAlexei Starovoitov int map_fd; 16*00899e7eSAlexei Starovoitov int prog_fd; 17*00899e7eSAlexei Starovoitov }; 18*00899e7eSAlexei Starovoitov 19*00899e7eSAlexei Starovoitov SEC("syscall") 20*00899e7eSAlexei Starovoitov int bpf_prog(struct args *ctx) 21*00899e7eSAlexei Starovoitov { 22*00899e7eSAlexei Starovoitov static char license[] = "GPL"; 23*00899e7eSAlexei Starovoitov static struct bpf_insn insns[] = { 24*00899e7eSAlexei Starovoitov BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 25*00899e7eSAlexei Starovoitov BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 26*00899e7eSAlexei Starovoitov BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 27*00899e7eSAlexei Starovoitov BPF_LD_MAP_FD(BPF_REG_1, 0), 28*00899e7eSAlexei Starovoitov BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 29*00899e7eSAlexei Starovoitov BPF_MOV64_IMM(BPF_REG_0, 0), 30*00899e7eSAlexei Starovoitov BPF_EXIT_INSN(), 31*00899e7eSAlexei Starovoitov }; 32*00899e7eSAlexei Starovoitov static union bpf_attr map_create_attr = { 33*00899e7eSAlexei Starovoitov .map_type = BPF_MAP_TYPE_HASH, 34*00899e7eSAlexei Starovoitov .key_size = 8, 35*00899e7eSAlexei Starovoitov .value_size = 8, 36*00899e7eSAlexei Starovoitov }; 37*00899e7eSAlexei Starovoitov static union bpf_attr map_update_attr = { .map_fd = 1, }; 38*00899e7eSAlexei Starovoitov static __u64 key = 12; 39*00899e7eSAlexei Starovoitov static __u64 value = 34; 40*00899e7eSAlexei Starovoitov static union bpf_attr prog_load_attr = { 41*00899e7eSAlexei Starovoitov .prog_type = BPF_PROG_TYPE_XDP, 42*00899e7eSAlexei Starovoitov .insn_cnt = sizeof(insns) / sizeof(insns[0]), 43*00899e7eSAlexei Starovoitov }; 44*00899e7eSAlexei Starovoitov int ret; 45*00899e7eSAlexei Starovoitov 46*00899e7eSAlexei Starovoitov map_create_attr.max_entries = ctx->max_entries; 47*00899e7eSAlexei Starovoitov prog_load_attr.license = (long) license; 48*00899e7eSAlexei Starovoitov prog_load_attr.insns = (long) insns; 49*00899e7eSAlexei Starovoitov prog_load_attr.log_buf = ctx->log_buf; 50*00899e7eSAlexei Starovoitov prog_load_attr.log_size = ctx->log_size; 51*00899e7eSAlexei Starovoitov prog_load_attr.log_level = 1; 52*00899e7eSAlexei Starovoitov 53*00899e7eSAlexei Starovoitov ret = bpf_sys_bpf(BPF_MAP_CREATE, &map_create_attr, sizeof(map_create_attr)); 54*00899e7eSAlexei Starovoitov if (ret <= 0) 55*00899e7eSAlexei Starovoitov return ret; 56*00899e7eSAlexei Starovoitov ctx->map_fd = ret; 57*00899e7eSAlexei Starovoitov insns[3].imm = ret; 58*00899e7eSAlexei Starovoitov 59*00899e7eSAlexei Starovoitov map_update_attr.map_fd = ret; 60*00899e7eSAlexei Starovoitov map_update_attr.key = (long) &key; 61*00899e7eSAlexei Starovoitov map_update_attr.value = (long) &value; 62*00899e7eSAlexei Starovoitov ret = bpf_sys_bpf(BPF_MAP_UPDATE_ELEM, &map_update_attr, sizeof(map_update_attr)); 63*00899e7eSAlexei Starovoitov if (ret < 0) 64*00899e7eSAlexei Starovoitov return ret; 65*00899e7eSAlexei Starovoitov 66*00899e7eSAlexei Starovoitov ret = bpf_sys_bpf(BPF_PROG_LOAD, &prog_load_attr, sizeof(prog_load_attr)); 67*00899e7eSAlexei Starovoitov if (ret <= 0) 68*00899e7eSAlexei Starovoitov return ret; 69*00899e7eSAlexei Starovoitov ctx->prog_fd = ret; 70*00899e7eSAlexei Starovoitov return 1; 71*00899e7eSAlexei Starovoitov } 72