Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2021 Facebook */
  3#include <linux/stddef.h>
  4#include <linux/bpf.h>
  5#include <bpf/bpf_helpers.h>
  6#include <bpf/bpf_tracing.h>
  7#include <../../../tools/include/linux/filter.h>
  8#include <linux/btf.h>
  9#include <string.h>
 10#include <errno.h>
 11#include "bpf_misc.h"
 12
 13char _license[] SEC("license") = "GPL";
 14
 15struct bpf_map {
 16	int id;
 17}  __attribute__((preserve_access_index));
 18
 19struct args {
 20	__u64 log_buf;
 21	__u32 log_size;
 22	int max_entries;
 23	int map_fd;
 24	int prog_fd;
 25	int btf_fd;
 26};
 27
 28#define BTF_INFO_ENC(kind, kind_flag, vlen) \
 29	((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
 30#define BTF_TYPE_ENC(name, info, size_or_type) (name), (info), (size_or_type)
 31#define BTF_INT_ENC(encoding, bits_offset, nr_bits) \
 32	((encoding) << 24 | (bits_offset) << 16 | (nr_bits))
 33#define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \
 34	BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \
 35	BTF_INT_ENC(encoding, bits_offset, bits)
 36
 37struct {
 38	__uint(type, BPF_MAP_TYPE_ARRAY);
 39	__type(key, int);
 40	__type(value, union bpf_attr);
 41	__uint(max_entries, 1);
 42} bpf_attr_array SEC(".maps");
 43
 44struct inner_map_type {
 45	__uint(type, BPF_MAP_TYPE_ARRAY);
 46	__uint(key_size, 4);
 47	__uint(value_size, 4);
 48	__uint(max_entries, 1);
 49} inner_map SEC(".maps");
 50
 51struct {
 52	__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
 53	__type(key, int);
 54	__type(value, int);
 55	__uint(max_entries, 1);
 56	__array(values, struct inner_map_type);
 57} outer_array_map SEC(".maps") = {
 58	.values = {
 59		[0] = &inner_map,
 60	},
 61};
 62
 63static inline __u64 ptr_to_u64(const void *ptr)
 64{
 65	return (__u64) (unsigned long) ptr;
 66}
 67
 68static int btf_load(void)
 69{
 70	struct btf_blob {
 71		struct btf_header btf_hdr;
 72		__u32 types[8];
 73		__u32 str;
 74	} raw_btf = {
 75		.btf_hdr = {
 76			.magic = BTF_MAGIC,
 77			.version = BTF_VERSION,
 78			.hdr_len = sizeof(struct btf_header),
 79			.type_len = sizeof(__u32) * 8,
 80			.str_off = sizeof(__u32) * 8,
 81			.str_len = sizeof(__u32),
 82		},
 83		.types = {
 84			/* long */
 85			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),  /* [1] */
 86			/* unsigned long */
 87			BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),  /* [2] */
 88		},
 89	};
 90	static union bpf_attr btf_load_attr = {
 91		.btf_size = sizeof(raw_btf),
 92	};
 93
 94	btf_load_attr.btf = (long)&raw_btf;
 95	return bpf_sys_bpf(BPF_BTF_LOAD, &btf_load_attr, sizeof(btf_load_attr));
 96}
 97
 98SEC("syscall")
 99int load_prog(struct args *ctx)
100{
101	static char license[] = "GPL";
102	static struct bpf_insn insns[] = {
103		BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
104		BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
105		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
106		BPF_LD_MAP_FD(BPF_REG_1, 0),
107		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
108		BPF_MOV64_IMM(BPF_REG_0, 0),
109		BPF_EXIT_INSN(),
110	};
111	static union bpf_attr map_create_attr = {
112		.map_type = BPF_MAP_TYPE_HASH,
113		.key_size = 8,
114		.value_size = 8,
115		.btf_key_type_id = 1,
116		.btf_value_type_id = 2,
117	};
118	static union bpf_attr map_update_attr = { .map_fd = 1, };
119	static __u64 key = 12;
120	static __u64 value = 34;
121	static union bpf_attr prog_load_attr = {
122		.prog_type = BPF_PROG_TYPE_XDP,
123		.insn_cnt = ARRAY_SIZE(insns),
124	};
125	int ret;
126
127	ret = btf_load();
128	if (ret <= 0)
129		return ret;
130
131	ctx->btf_fd = ret;
132	map_create_attr.max_entries = ctx->max_entries;
133	map_create_attr.btf_fd = ret;
134
135	prog_load_attr.license = ptr_to_u64(license);
136	prog_load_attr.insns = ptr_to_u64(insns);
137	prog_load_attr.log_buf = ctx->log_buf;
138	prog_load_attr.log_size = ctx->log_size;
139	prog_load_attr.log_level = 1;
140
141	ret = bpf_sys_bpf(BPF_MAP_CREATE, &map_create_attr, sizeof(map_create_attr));
142	if (ret <= 0)
143		return ret;
144	ctx->map_fd = ret;
145	insns[3].imm = ret;
146
147	map_update_attr.map_fd = ret;
148	map_update_attr.key = ptr_to_u64(&key);
149	map_update_attr.value = ptr_to_u64(&value);
150	ret = bpf_sys_bpf(BPF_MAP_UPDATE_ELEM, &map_update_attr, sizeof(map_update_attr));
151	if (ret < 0)
152		return ret;
153
154	ret = bpf_sys_bpf(BPF_PROG_LOAD, &prog_load_attr, sizeof(prog_load_attr));
155	if (ret <= 0)
156		return ret;
157	ctx->prog_fd = ret;
158	return 1;
159}
160
161SEC("syscall")
162int update_outer_map(void *ctx)
163{
164	int zero = 0, ret = 0, outer_fd = -1, inner_fd = -1, err;
165	const int attr_sz = sizeof(union bpf_attr);
166	union bpf_attr *attr;
167
168	attr = bpf_map_lookup_elem((struct bpf_map *)&bpf_attr_array, &zero);
169	if (!attr)
170		goto out;
171
172	memset(attr, 0, attr_sz);
173	attr->map_id = ((struct bpf_map *)&outer_array_map)->id;
174	outer_fd = bpf_sys_bpf(BPF_MAP_GET_FD_BY_ID, attr, attr_sz);
175	if (outer_fd < 0)
176		goto out;
177
178	memset(attr, 0, attr_sz);
179	attr->map_type = BPF_MAP_TYPE_ARRAY;
180	attr->key_size = 4;
181	attr->value_size = 4;
182	attr->max_entries = 1;
183	inner_fd = bpf_sys_bpf(BPF_MAP_CREATE, attr, attr_sz);
184	if (inner_fd < 0)
185		goto out;
186
187	memset(attr, 0, attr_sz);
188	attr->map_fd = outer_fd;
189	attr->key = ptr_to_u64(&zero);
190	attr->value = ptr_to_u64(&inner_fd);
191	err = bpf_sys_bpf(BPF_MAP_UPDATE_ELEM, attr, attr_sz);
192	if (err)
193		goto out;
194
195	memset(attr, 0, attr_sz);
196	attr->map_fd = outer_fd;
197	attr->key = ptr_to_u64(&zero);
198	err = bpf_sys_bpf(BPF_MAP_DELETE_ELEM, attr, attr_sz);
199	if (err)
200		goto out;
201	ret = 1;
202out:
203	if (inner_fd >= 0)
204		bpf_sys_close(inner_fd);
205	if (outer_fd >= 0)
206		bpf_sys_close(outer_fd);
207	return ret;
208}
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2021 Facebook */
  3#include <linux/stddef.h>
  4#include <linux/bpf.h>
  5#include <bpf/bpf_helpers.h>
  6#include <bpf/bpf_tracing.h>
  7#include <../../../tools/include/linux/filter.h>
  8#include <linux/btf.h>
 
 
 
  9
 10char _license[] SEC("license") = "GPL";
 11
 
 
 
 
 12struct args {
 13	__u64 log_buf;
 14	__u32 log_size;
 15	int max_entries;
 16	int map_fd;
 17	int prog_fd;
 18	int btf_fd;
 19};
 20
 21#define BTF_INFO_ENC(kind, kind_flag, vlen) \
 22	((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
 23#define BTF_TYPE_ENC(name, info, size_or_type) (name), (info), (size_or_type)
 24#define BTF_INT_ENC(encoding, bits_offset, nr_bits) \
 25	((encoding) << 24 | (bits_offset) << 16 | (nr_bits))
 26#define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \
 27	BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \
 28	BTF_INT_ENC(encoding, bits_offset, bits)
 29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 30static int btf_load(void)
 31{
 32	struct btf_blob {
 33		struct btf_header btf_hdr;
 34		__u32 types[8];
 35		__u32 str;
 36	} raw_btf = {
 37		.btf_hdr = {
 38			.magic = BTF_MAGIC,
 39			.version = BTF_VERSION,
 40			.hdr_len = sizeof(struct btf_header),
 41			.type_len = sizeof(__u32) * 8,
 42			.str_off = sizeof(__u32) * 8,
 43			.str_len = sizeof(__u32),
 44		},
 45		.types = {
 46			/* long */
 47			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),  /* [1] */
 48			/* unsigned long */
 49			BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),  /* [2] */
 50		},
 51	};
 52	static union bpf_attr btf_load_attr = {
 53		.btf_size = sizeof(raw_btf),
 54	};
 55
 56	btf_load_attr.btf = (long)&raw_btf;
 57	return bpf_sys_bpf(BPF_BTF_LOAD, &btf_load_attr, sizeof(btf_load_attr));
 58}
 59
 60SEC("syscall")
 61int bpf_prog(struct args *ctx)
 62{
 63	static char license[] = "GPL";
 64	static struct bpf_insn insns[] = {
 65		BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 66		BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 67		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 68		BPF_LD_MAP_FD(BPF_REG_1, 0),
 69		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 70		BPF_MOV64_IMM(BPF_REG_0, 0),
 71		BPF_EXIT_INSN(),
 72	};
 73	static union bpf_attr map_create_attr = {
 74		.map_type = BPF_MAP_TYPE_HASH,
 75		.key_size = 8,
 76		.value_size = 8,
 77		.btf_key_type_id = 1,
 78		.btf_value_type_id = 2,
 79	};
 80	static union bpf_attr map_update_attr = { .map_fd = 1, };
 81	static __u64 key = 12;
 82	static __u64 value = 34;
 83	static union bpf_attr prog_load_attr = {
 84		.prog_type = BPF_PROG_TYPE_XDP,
 85		.insn_cnt = sizeof(insns) / sizeof(insns[0]),
 86	};
 87	int ret;
 88
 89	ret = btf_load();
 90	if (ret <= 0)
 91		return ret;
 92
 93	ctx->btf_fd = ret;
 94	map_create_attr.max_entries = ctx->max_entries;
 95	map_create_attr.btf_fd = ret;
 96
 97	prog_load_attr.license = (long) license;
 98	prog_load_attr.insns = (long) insns;
 99	prog_load_attr.log_buf = ctx->log_buf;
100	prog_load_attr.log_size = ctx->log_size;
101	prog_load_attr.log_level = 1;
102
103	ret = bpf_sys_bpf(BPF_MAP_CREATE, &map_create_attr, sizeof(map_create_attr));
104	if (ret <= 0)
105		return ret;
106	ctx->map_fd = ret;
107	insns[3].imm = ret;
108
109	map_update_attr.map_fd = ret;
110	map_update_attr.key = (long) &key;
111	map_update_attr.value = (long) &value;
112	ret = bpf_sys_bpf(BPF_MAP_UPDATE_ELEM, &map_update_attr, sizeof(map_update_attr));
113	if (ret < 0)
114		return ret;
115
116	ret = bpf_sys_bpf(BPF_PROG_LOAD, &prog_load_attr, sizeof(prog_load_attr));
117	if (ret <= 0)
118		return ret;
119	ctx->prog_fd = ret;
120	return 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121}