Blame view

tools/lib/bpf/bpf.c 24 KB
1bc38b8ff   Alexei Starovoitov   libbpf: relicense...
1
  // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
6061a3d67   Eric Leblond   libbpf: add missi...
2

e3ed2fef2   Wang Nan   bpf tools: Add bp...
3
4
5
6
7
8
  /*
   * common eBPF ELF operations.
   *
   * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
   * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
   * Copyright (C) 2015 Huawei Inc.
203d1caca   Wang Nan   tools lib bpf: Ad...
9
10
11
12
13
14
15
16
17
18
19
20
21
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation;
   * version 2.1 of the License (not later!)
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this program; if not,  see <http://www.gnu.org/licenses>
e3ed2fef2   Wang Nan   bpf tools: Add bp...
22
23
24
   */
  
  #include <stdlib.h>
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
25
  #include <string.h>
e3ed2fef2   Wang Nan   bpf tools: Add bp...
26
27
28
  #include <memory.h>
  #include <unistd.h>
  #include <asm/unistd.h>
d7fe74f94   Andrii Nakryiko   libbpf: add commo...
29
  #include <errno.h>
e3ed2fef2   Wang Nan   bpf tools: Add bp...
30
31
  #include <linux/bpf.h>
  #include "bpf.h"
949abbe88   Eric Leblond   libbpf: add funct...
32
  #include "libbpf.h"
d7fe74f94   Andrii Nakryiko   libbpf: add commo...
33
  #include "libbpf_internal.h"
e3ed2fef2   Wang Nan   bpf tools: Add bp...
34
35
  
  /*
03671057c   Masahiro Yamada   scripts/spelling....
36
   * When building perf, unistd.h is overridden. __NR_bpf is
8f9e05fb2   Wang Nan   perf tools: Fix P...
37
   * required to be defined explicitly.
e3ed2fef2   Wang Nan   bpf tools: Add bp...
38
39
40
41
42
43
44
45
   */
  #ifndef __NR_bpf
  # if defined(__i386__)
  #  define __NR_bpf 357
  # elif defined(__x86_64__)
  #  define __NR_bpf 321
  # elif defined(__aarch64__)
  #  define __NR_bpf 280
b0c47807d   David S. Miller   bpf: Add sparc su...
46
47
  # elif defined(__sparc__)
  #  define __NR_bpf 349
bad1926dd   Daniel Borkmann   bpf, s390: fix bu...
48
49
  # elif defined(__s390__)
  #  define __NR_bpf 351
ca31ca824   Vineet Gupta   tools/bpf: fix pe...
50
51
  # elif defined(__arc__)
  #  define __NR_bpf 280
e3ed2fef2   Wang Nan   bpf tools: Add bp...
52
53
54
55
  # else
  #  error __NR_bpf not defined. libbpf does not support your arch.
  # endif
  #endif
cdc6a4ba8   Mickaël Salaün   bpf: Remove redun...
56
  static inline __u64 ptr_to_u64(const void *ptr)
7bf98369a   Wang Nan   bpf tools: Introd...
57
58
59
  {
  	return (__u64) (unsigned long) ptr;
  }
cdc6a4ba8   Mickaël Salaün   bpf: Remove redun...
60
61
  static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
  			  unsigned int size)
e3ed2fef2   Wang Nan   bpf tools: Add bp...
62
63
64
  {
  	return syscall(__NR_bpf, cmd, attr, size);
  }
86edaed37   Lorenz Bauer   bpf: libbpf: retr...
65
66
67
68
69
70
71
72
73
74
  static inline int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size)
  {
  	int fd;
  
  	do {
  		fd = sys_bpf(BPF_PROG_LOAD, attr, size);
  	} while (fd < 0 && errno == EAGAIN);
  
  	return fd;
  }
8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
75
  int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr)
e3ed2fef2   Wang Nan   bpf tools: Add bp...
76
77
78
79
  {
  	union bpf_attr attr;
  
  	memset(&attr, '\0', sizeof(attr));
8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
80
81
82
83
84
  	attr.map_type = create_attr->map_type;
  	attr.key_size = create_attr->key_size;
  	attr.value_size = create_attr->value_size;
  	attr.max_entries = create_attr->max_entries;
  	attr.map_flags = create_attr->map_flags;
69a0f9ece   Yonghong Song   bpf, bpftool: fix...
85
86
87
  	if (create_attr->name)
  		memcpy(attr.map_name, create_attr->name,
  		       min(strlen(create_attr->name), BPF_OBJ_NAME_LEN - 1));
8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
88
89
  	attr.numa_node = create_attr->numa_node;
  	attr.btf_fd = create_attr->btf_fd;
61746dbe1   Martin KaFai Lau   bpf: btf: Add tes...
90
91
  	attr.btf_key_type_id = create_attr->btf_key_type_id;
  	attr.btf_value_type_id = create_attr->btf_value_type_id;
f0307a7ed   David Beckett   libbpf: add ifind...
92
  	attr.map_ifindex = create_attr->map_ifindex;
590a00888   Martin KaFai Lau   bpf: libbpf: Add ...
93
94
95
96
97
  	if (attr.map_type == BPF_MAP_TYPE_STRUCT_OPS)
  		attr.btf_vmlinux_value_type_id =
  			create_attr->btf_vmlinux_value_type_id;
  	else
  		attr.inner_map_fd = create_attr->inner_map_fd;
8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
98

94cb310cf   Stanislav Fomichev   bpf: libbpf: remo...
99
  	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
100
  }
88cda1c9d   Martin KaFai Lau   bpf: libbpf: Prov...
101

8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
102
103
104
105
106
107
108
109
110
111
112
113
  int bpf_create_map_node(enum bpf_map_type map_type, const char *name,
  			int key_size, int value_size, int max_entries,
  			__u32 map_flags, int node)
  {
  	struct bpf_create_map_attr map_attr = {};
  
  	map_attr.name = name;
  	map_attr.map_type = map_type;
  	map_attr.map_flags = map_flags;
  	map_attr.key_size = key_size;
  	map_attr.value_size = value_size;
  	map_attr.max_entries = max_entries;
ad17d0e6c   Martin KaFai Lau   bpf: Allow numa s...
114
  	if (node >= 0) {
8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
115
116
  		map_attr.numa_node = node;
  		map_attr.map_flags |= BPF_F_NUMA_NODE;
ad17d0e6c   Martin KaFai Lau   bpf: Allow numa s...
117
  	}
e3ed2fef2   Wang Nan   bpf tools: Add bp...
118

8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
119
  	return bpf_create_map_xattr(&map_attr);
e3ed2fef2   Wang Nan   bpf tools: Add bp...
120
  }
7bf98369a   Wang Nan   bpf tools: Introd...
121

ad17d0e6c   Martin KaFai Lau   bpf: Allow numa s...
122
123
124
  int bpf_create_map(enum bpf_map_type map_type, int key_size,
  		   int value_size, int max_entries, __u32 map_flags)
  {
8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
125
126
127
128
129
130
131
132
133
  	struct bpf_create_map_attr map_attr = {};
  
  	map_attr.map_type = map_type;
  	map_attr.map_flags = map_flags;
  	map_attr.key_size = key_size;
  	map_attr.value_size = value_size;
  	map_attr.max_entries = max_entries;
  
  	return bpf_create_map_xattr(&map_attr);
ad17d0e6c   Martin KaFai Lau   bpf: Allow numa s...
134
  }
88cda1c9d   Martin KaFai Lau   bpf: libbpf: Prov...
135
136
137
138
  int bpf_create_map_name(enum bpf_map_type map_type, const char *name,
  			int key_size, int value_size, int max_entries,
  			__u32 map_flags)
  {
8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
139
140
141
142
143
144
145
146
147
148
  	struct bpf_create_map_attr map_attr = {};
  
  	map_attr.name = name;
  	map_attr.map_type = map_type;
  	map_attr.map_flags = map_flags;
  	map_attr.key_size = key_size;
  	map_attr.value_size = value_size;
  	map_attr.max_entries = max_entries;
  
  	return bpf_create_map_xattr(&map_attr);
88cda1c9d   Martin KaFai Lau   bpf: libbpf: Prov...
149
150
151
152
  }
  
  int bpf_create_map_in_map_node(enum bpf_map_type map_type, const char *name,
  			       int key_size, int inner_map_fd, int max_entries,
ad17d0e6c   Martin KaFai Lau   bpf: Allow numa s...
153
  			       __u32 map_flags, int node)
fb30d4b71   Martin KaFai Lau   bpf: Add tests fo...
154
155
156
157
158
159
160
161
162
163
164
  {
  	union bpf_attr attr;
  
  	memset(&attr, '\0', sizeof(attr));
  
  	attr.map_type = map_type;
  	attr.key_size = key_size;
  	attr.value_size = 4;
  	attr.inner_map_fd = inner_map_fd;
  	attr.max_entries = max_entries;
  	attr.map_flags = map_flags;
69a0f9ece   Yonghong Song   bpf, bpftool: fix...
165
166
167
  	if (name)
  		memcpy(attr.map_name, name,
  		       min(strlen(name), BPF_OBJ_NAME_LEN - 1));
88cda1c9d   Martin KaFai Lau   bpf: libbpf: Prov...
168

ad17d0e6c   Martin KaFai Lau   bpf: Allow numa s...
169
170
171
172
  	if (node >= 0) {
  		attr.map_flags |= BPF_F_NUMA_NODE;
  		attr.numa_node = node;
  	}
fb30d4b71   Martin KaFai Lau   bpf: Add tests fo...
173
174
175
  
  	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
  }
88cda1c9d   Martin KaFai Lau   bpf: libbpf: Prov...
176
177
178
  int bpf_create_map_in_map(enum bpf_map_type map_type, const char *name,
  			  int key_size, int inner_map_fd, int max_entries,
  			  __u32 map_flags)
ad17d0e6c   Martin KaFai Lau   bpf: Allow numa s...
179
  {
88cda1c9d   Martin KaFai Lau   bpf: libbpf: Prov...
180
181
182
  	return bpf_create_map_in_map_node(map_type, name, key_size,
  					  inner_map_fd, max_entries, map_flags,
  					  -1);
ad17d0e6c   Martin KaFai Lau   bpf: Allow numa s...
183
  }
3d6501414   Martin KaFai Lau   bpf: libbpf: Add ...
184
185
186
187
  static void *
  alloc_zero_tailing_info(const void *orecord, __u32 cnt,
  			__u32 actual_rec_size, __u32 expected_rec_size)
  {
4ee113561   Andrii Nakryiko   libbpf: Fix poten...
188
  	__u64 info_len = (__u64)actual_rec_size * cnt;
3d6501414   Martin KaFai Lau   bpf: libbpf: Add ...
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  	void *info, *nrecord;
  	int i;
  
  	info = malloc(info_len);
  	if (!info)
  		return NULL;
  
  	/* zero out bytes kernel does not understand */
  	nrecord = info;
  	for (i = 0; i < cnt; i++) {
  		memcpy(nrecord, orecord, expected_rec_size);
  		memset(nrecord + expected_rec_size, 0,
  		       actual_rec_size - expected_rec_size);
  		orecord += actual_rec_size;
  		nrecord += actual_rec_size;
  	}
  
  	return info;
  }
d7be143b6   Andrey Ignatov   libbpf: Support e...
208
209
  int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
  			   char *log_buf, size_t log_buf_sz)
7bf98369a   Wang Nan   bpf tools: Introd...
210
  {
3d6501414   Martin KaFai Lau   bpf: libbpf: Add ...
211
  	void *finfo = NULL, *linfo = NULL;
7bf98369a   Wang Nan   bpf tools: Introd...
212
  	union bpf_attr attr;
a4021a357   Yonghong Song   tools/bpf: add lo...
213
  	__u32 log_level;
d7be143b6   Andrey Ignatov   libbpf: Support e...
214
  	int fd;
a4021a357   Yonghong Song   tools/bpf: add lo...
215
216
217
218
  	if (!load_attr || !log_buf != !log_buf_sz)
  		return -EINVAL;
  
  	log_level = load_attr->log_level;
da11b4175   Alexei Starovoitov   libbpf: teach lib...
219
  	if (log_level > (4 | 2 | 1) || (log_level && !log_buf))
d7be143b6   Andrey Ignatov   libbpf: Support e...
220
  		return -EINVAL;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
221
  	memset(&attr, 0, sizeof(attr));
d7be143b6   Andrey Ignatov   libbpf: Support e...
222
223
  	attr.prog_type = load_attr->prog_type;
  	attr.expected_attach_type = load_attr->expected_attach_type;
1e092a031   KP Singh   tools/libbpf: Add...
224
225
  	if (attr.prog_type == BPF_PROG_TYPE_STRUCT_OPS ||
  	    attr.prog_type == BPF_PROG_TYPE_LSM) {
590a00888   Martin KaFai Lau   bpf: libbpf: Add ...
226
  		attr.attach_btf_id = load_attr->attach_btf_id;
2db6eab18   Alexei Starovoitov   libbpf: Add suppo...
227
228
  	} else if (attr.prog_type == BPF_PROG_TYPE_TRACING ||
  		   attr.prog_type == BPF_PROG_TYPE_EXT) {
12a8654b2   Alexei Starovoitov   libbpf: Add suppo...
229
  		attr.attach_btf_id = load_attr->attach_btf_id;
e7bf94dbb   Alexei Starovoitov   libbpf: Add suppo...
230
231
  		attr.attach_prog_fd = load_attr->attach_prog_fd;
  	} else {
12a8654b2   Alexei Starovoitov   libbpf: Add suppo...
232
  		attr.prog_ifindex = load_attr->prog_ifindex;
e7bf94dbb   Alexei Starovoitov   libbpf: Add suppo...
233
234
  		attr.kern_version = load_attr->kern_version;
  	}
d7be143b6   Andrey Ignatov   libbpf: Support e...
235
236
237
  	attr.insn_cnt = (__u32)load_attr->insns_cnt;
  	attr.insns = ptr_to_u64(load_attr->insns);
  	attr.license = ptr_to_u64(load_attr->license);
a4021a357   Yonghong Song   tools/bpf: add lo...
238
239
240
241
242
243
244
245
246
  
  	attr.log_level = log_level;
  	if (log_level) {
  		attr.log_buf = ptr_to_u64(log_buf);
  		attr.log_size = log_buf_sz;
  	} else {
  		attr.log_buf = ptr_to_u64(NULL);
  		attr.log_size = 0;
  	}
7e0d0fb55   Yonghong Song   tools/bpf: add ne...
247
248
249
250
  	attr.prog_btf_fd = load_attr->prog_btf_fd;
  	attr.func_info_rec_size = load_attr->func_info_rec_size;
  	attr.func_info_cnt = load_attr->func_info_cnt;
  	attr.func_info = ptr_to_u64(load_attr->func_info);
3d6501414   Martin KaFai Lau   bpf: libbpf: Add ...
251
252
253
  	attr.line_info_rec_size = load_attr->line_info_rec_size;
  	attr.line_info_cnt = load_attr->line_info_cnt;
  	attr.line_info = ptr_to_u64(load_attr->line_info);
69a0f9ece   Yonghong Song   bpf, bpftool: fix...
254
255
256
  	if (load_attr->name)
  		memcpy(attr.prog_name, load_attr->name,
  		       min(strlen(load_attr->name), BPF_OBJ_NAME_LEN - 1));
046561981   Jiong Wang   libbpf: add "prog...
257
  	attr.prog_flags = load_attr->prog_flags;
7bf98369a   Wang Nan   bpf tools: Introd...
258

86edaed37   Lorenz Bauer   bpf: libbpf: retr...
259
  	fd = sys_bpf_prog_load(&attr, sizeof(attr));
f0187f0b1   Martin KaFai Lau   bpf: libbpf: Refa...
260
  	if (fd >= 0)
7bf98369a   Wang Nan   bpf tools: Introd...
261
  		return fd;
2993e0515   Yonghong Song   tools/bpf: add su...
262
263
264
265
  	/* After bpf_prog_load, the kernel may modify certain attributes
  	 * to give user space a hint how to deal with loading failure.
  	 * Check to see whether we can make some changes and load again.
  	 */
3d6501414   Martin KaFai Lau   bpf: libbpf: Add ...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
  	while (errno == E2BIG && (!finfo || !linfo)) {
  		if (!finfo && attr.func_info_cnt &&
  		    attr.func_info_rec_size < load_attr->func_info_rec_size) {
  			/* try with corrected func info records */
  			finfo = alloc_zero_tailing_info(load_attr->func_info,
  							load_attr->func_info_cnt,
  							load_attr->func_info_rec_size,
  							attr.func_info_rec_size);
  			if (!finfo)
  				goto done;
  
  			attr.func_info = ptr_to_u64(finfo);
  			attr.func_info_rec_size = load_attr->func_info_rec_size;
  		} else if (!linfo && attr.line_info_cnt &&
  			   attr.line_info_rec_size <
  			   load_attr->line_info_rec_size) {
  			linfo = alloc_zero_tailing_info(load_attr->line_info,
  							load_attr->line_info_cnt,
  							load_attr->line_info_rec_size,
  							attr.line_info_rec_size);
  			if (!linfo)
  				goto done;
  
  			attr.line_info = ptr_to_u64(linfo);
  			attr.line_info_rec_size = load_attr->line_info_rec_size;
  		} else {
  			break;
2993e0515   Yonghong Song   tools/bpf: add su...
293
  		}
86edaed37   Lorenz Bauer   bpf: libbpf: retr...
294
  		fd = sys_bpf_prog_load(&attr, sizeof(attr));
2993e0515   Yonghong Song   tools/bpf: add su...
295

f0187f0b1   Martin KaFai Lau   bpf: libbpf: Refa...
296
  		if (fd >= 0)
2993e0515   Yonghong Song   tools/bpf: add su...
297
298
  			goto done;
  	}
a4021a357   Yonghong Song   tools/bpf: add lo...
299
  	if (log_level || !log_buf)
f0187f0b1   Martin KaFai Lau   bpf: libbpf: Refa...
300
  		goto done;
7bf98369a   Wang Nan   bpf tools: Introd...
301
302
303
304
305
  	/* Try again with log */
  	attr.log_buf = ptr_to_u64(log_buf);
  	attr.log_size = log_buf_sz;
  	attr.log_level = 1;
  	log_buf[0] = 0;
86edaed37   Lorenz Bauer   bpf: libbpf: retr...
306
  	fd = sys_bpf_prog_load(&attr, sizeof(attr));
2993e0515   Yonghong Song   tools/bpf: add su...
307
308
  done:
  	free(finfo);
3d6501414   Martin KaFai Lau   bpf: libbpf: Add ...
309
  	free(linfo);
2993e0515   Yonghong Song   tools/bpf: add su...
310
  	return fd;
7bf98369a   Wang Nan   bpf tools: Introd...
311
  }
43798bf37   He Kuang   bpf tools: Add he...
312

88cda1c9d   Martin KaFai Lau   bpf: libbpf: Prov...
313
314
315
316
317
  int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
  		     size_t insns_cnt, const char *license,
  		     __u32 kern_version, char *log_buf,
  		     size_t log_buf_sz)
  {
d7be143b6   Andrey Ignatov   libbpf: Support e...
318
319
320
321
322
323
324
325
326
327
328
329
  	struct bpf_load_program_attr load_attr;
  
  	memset(&load_attr, 0, sizeof(struct bpf_load_program_attr));
  	load_attr.prog_type = type;
  	load_attr.expected_attach_type = 0;
  	load_attr.name = NULL;
  	load_attr.insns = insns;
  	load_attr.insns_cnt = insns_cnt;
  	load_attr.license = license;
  	load_attr.kern_version = kern_version;
  
  	return bpf_load_program_xattr(&load_attr, log_buf, log_buf_sz);
88cda1c9d   Martin KaFai Lau   bpf: libbpf: Prov...
330
  }
91045f5e5   David S. Miller   bpf: Add bpf_veri...
331
  int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns,
e9ee9efc0   David Miller   bpf: Add BPF_F_AN...
332
333
334
  		       size_t insns_cnt, __u32 prog_flags, const char *license,
  		       __u32 kern_version, char *log_buf, size_t log_buf_sz,
  		       int log_level)
91045f5e5   David S. Miller   bpf: Add bpf_veri...
335
336
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
337
  	memset(&attr, 0, sizeof(attr));
91045f5e5   David S. Miller   bpf: Add bpf_veri...
338
339
340
341
342
343
  	attr.prog_type = type;
  	attr.insn_cnt = (__u32)insns_cnt;
  	attr.insns = ptr_to_u64(insns);
  	attr.license = ptr_to_u64(license);
  	attr.log_buf = ptr_to_u64(log_buf);
  	attr.log_size = log_buf_sz;
d65549041   Daniel Borkmann   bpf: allow to spe...
344
  	attr.log_level = log_level;
91045f5e5   David S. Miller   bpf: Add bpf_veri...
345
346
  	log_buf[0] = 0;
  	attr.kern_version = kern_version;
e9ee9efc0   David Miller   bpf: Add BPF_F_AN...
347
  	attr.prog_flags = prog_flags;
91045f5e5   David S. Miller   bpf: Add bpf_veri...
348

86edaed37   Lorenz Bauer   bpf: libbpf: retr...
349
  	return sys_bpf_prog_load(&attr, sizeof(attr));
91045f5e5   David S. Miller   bpf: Add bpf_veri...
350
  }
10ecc728f   Mickaël Salaün   bpf: Use bpf_map_...
351
  int bpf_map_update_elem(int fd, const void *key, const void *value,
83d994d02   Joe Stringer   tools lib bpf: us...
352
  			__u64 flags)
43798bf37   He Kuang   bpf tools: Add he...
353
354
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
355
  	memset(&attr, 0, sizeof(attr));
43798bf37   He Kuang   bpf tools: Add he...
356
357
358
359
360
361
362
  	attr.map_fd = fd;
  	attr.key = ptr_to_u64(key);
  	attr.value = ptr_to_u64(value);
  	attr.flags = flags;
  
  	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
  }
9742da015   Wang Nan   tools lib bpf: Ad...
363

e5ff7c401   Mickaël Salaün   bpf: Use bpf_map_...
364
  int bpf_map_lookup_elem(int fd, const void *key, void *value)
9742da015   Wang Nan   tools lib bpf: Ad...
365
366
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
367
  	memset(&attr, 0, sizeof(attr));
9742da015   Wang Nan   tools lib bpf: Ad...
368
369
370
371
372
373
  	attr.map_fd = fd;
  	attr.key = ptr_to_u64(key);
  	attr.value = ptr_to_u64(value);
  
  	return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
  }
df5d22fac   Alexei Starovoitov   libbpf: introduce...
374
375
376
  int bpf_map_lookup_elem_flags(int fd, const void *key, void *value, __u64 flags)
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
377
  	memset(&attr, 0, sizeof(attr));
df5d22fac   Alexei Starovoitov   libbpf: introduce...
378
379
380
381
382
383
384
  	attr.map_fd = fd;
  	attr.key = ptr_to_u64(key);
  	attr.value = ptr_to_u64(value);
  	attr.flags = flags;
  
  	return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
  }
43b987d23   Mauricio Vasquez B   selftests/bpf: ad...
385
386
387
  int bpf_map_lookup_and_delete_elem(int fd, const void *key, void *value)
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
388
  	memset(&attr, 0, sizeof(attr));
43b987d23   Mauricio Vasquez B   selftests/bpf: ad...
389
390
391
392
393
394
  	attr.map_fd = fd;
  	attr.key = ptr_to_u64(key);
  	attr.value = ptr_to_u64(value);
  
  	return sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr));
  }
e58383b80   Mickaël Salaün   bpf: Use bpf_map_...
395
  int bpf_map_delete_elem(int fd, const void *key)
9742da015   Wang Nan   tools lib bpf: Ad...
396
397
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
398
  	memset(&attr, 0, sizeof(attr));
9742da015   Wang Nan   tools lib bpf: Ad...
399
400
401
402
403
  	attr.map_fd = fd;
  	attr.key = ptr_to_u64(key);
  
  	return sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
  }
5f155c256   Mickaël Salaün   bpf: Use bpf_map_...
404
  int bpf_map_get_next_key(int fd, const void *key, void *next_key)
9742da015   Wang Nan   tools lib bpf: Ad...
405
406
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
407
  	memset(&attr, 0, sizeof(attr));
9742da015   Wang Nan   tools lib bpf: Ad...
408
409
410
411
412
413
  	attr.map_fd = fd;
  	attr.key = ptr_to_u64(key);
  	attr.next_key = ptr_to_u64(next_key);
  
  	return sys_bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
  }
d859900c4   Daniel Borkmann   bpf, libbpf: supp...
414
415
416
417
418
419
420
421
422
  int bpf_map_freeze(int fd)
  {
  	union bpf_attr attr;
  
  	memset(&attr, 0, sizeof(attr));
  	attr.map_fd = fd;
  
  	return sys_bpf(BPF_MAP_FREEZE, &attr, sizeof(attr));
  }
2ab3d86ea   Yonghong Song   libbpf: Add libbp...
423
424
425
426
427
  static int bpf_map_batch_common(int cmd, int fd, void  *in_batch,
  				void *out_batch, void *keys, void *values,
  				__u32 *count,
  				const struct bpf_map_batch_opts *opts)
  {
858e284f0   Brian Vazquez   libbpf: Fix unnee...
428
  	union bpf_attr attr;
2ab3d86ea   Yonghong Song   libbpf: Add libbp...
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
  	int ret;
  
  	if (!OPTS_VALID(opts, bpf_map_batch_opts))
  		return -EINVAL;
  
  	memset(&attr, 0, sizeof(attr));
  	attr.batch.map_fd = fd;
  	attr.batch.in_batch = ptr_to_u64(in_batch);
  	attr.batch.out_batch = ptr_to_u64(out_batch);
  	attr.batch.keys = ptr_to_u64(keys);
  	attr.batch.values = ptr_to_u64(values);
  	attr.batch.count = *count;
  	attr.batch.elem_flags  = OPTS_GET(opts, elem_flags, 0);
  	attr.batch.flags = OPTS_GET(opts, flags, 0);
  
  	ret = sys_bpf(cmd, &attr, sizeof(attr));
  	*count = attr.batch.count;
  
  	return ret;
  }
  
  int bpf_map_delete_batch(int fd, void *keys, __u32 *count,
  			 const struct bpf_map_batch_opts *opts)
  {
  	return bpf_map_batch_common(BPF_MAP_DELETE_BATCH, fd, NULL,
  				    NULL, keys, NULL, count, opts);
  }
  
  int bpf_map_lookup_batch(int fd, void *in_batch, void *out_batch, void *keys,
  			 void *values, __u32 *count,
  			 const struct bpf_map_batch_opts *opts)
  {
  	return bpf_map_batch_common(BPF_MAP_LOOKUP_BATCH, fd, in_batch,
  				    out_batch, keys, values, count, opts);
  }
  
  int bpf_map_lookup_and_delete_batch(int fd, void *in_batch, void *out_batch,
  				    void *keys, void *values, __u32 *count,
  				    const struct bpf_map_batch_opts *opts)
  {
  	return bpf_map_batch_common(BPF_MAP_LOOKUP_AND_DELETE_BATCH,
  				    fd, in_batch, out_batch, keys, values,
  				    count, opts);
  }
  
  int bpf_map_update_batch(int fd, void *keys, void *values, __u32 *count,
  			 const struct bpf_map_batch_opts *opts)
  {
  	return bpf_map_batch_common(BPF_MAP_UPDATE_BATCH, fd, NULL, NULL,
  				    keys, values, count, opts);
  }
9742da015   Wang Nan   tools lib bpf: Ad...
480
481
482
  int bpf_obj_pin(int fd, const char *pathname)
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
483
  	memset(&attr, 0, sizeof(attr));
9742da015   Wang Nan   tools lib bpf: Ad...
484
485
486
487
488
489
490
491
492
  	attr.pathname = ptr_to_u64((void *)pathname);
  	attr.bpf_fd = fd;
  
  	return sys_bpf(BPF_OBJ_PIN, &attr, sizeof(attr));
  }
  
  int bpf_obj_get(const char *pathname)
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
493
  	memset(&attr, 0, sizeof(attr));
9742da015   Wang Nan   tools lib bpf: Ad...
494
495
496
497
  	attr.pathname = ptr_to_u64((void *)pathname);
  
  	return sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr));
  }
5dc880de6   Joe Stringer   tools lib bpf: Ad...
498

464bc0fd6   John Fastabend   bpf: convert sock...
499
500
  int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type,
  		    unsigned int flags)
5dc880de6   Joe Stringer   tools lib bpf: Ad...
501
  {
cdbee3839   Andrey Ignatov   libbpf: Introduce...
502
503
504
505
506
507
508
509
510
511
512
  	DECLARE_LIBBPF_OPTS(bpf_prog_attach_opts, opts,
  		.flags = flags,
  	);
  
  	return bpf_prog_attach_xattr(prog_fd, target_fd, type, &opts);
  }
  
  int bpf_prog_attach_xattr(int prog_fd, int target_fd,
  			  enum bpf_attach_type type,
  			  const struct bpf_prog_attach_opts *opts)
  {
5dc880de6   Joe Stringer   tools lib bpf: Ad...
513
  	union bpf_attr attr;
cdbee3839   Andrey Ignatov   libbpf: Introduce...
514
515
  	if (!OPTS_VALID(opts, bpf_prog_attach_opts))
  		return -EINVAL;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
516
  	memset(&attr, 0, sizeof(attr));
5dc880de6   Joe Stringer   tools lib bpf: Ad...
517
  	attr.target_fd	   = target_fd;
464bc0fd6   John Fastabend   bpf: convert sock...
518
  	attr.attach_bpf_fd = prog_fd;
5dc880de6   Joe Stringer   tools lib bpf: Ad...
519
  	attr.attach_type   = type;
cdbee3839   Andrey Ignatov   libbpf: Introduce...
520
521
  	attr.attach_flags  = OPTS_GET(opts, flags, 0);
  	attr.replace_bpf_fd = OPTS_GET(opts, replace_prog_fd, 0);
5dc880de6   Joe Stringer   tools lib bpf: Ad...
522
523
524
525
526
527
528
  
  	return sys_bpf(BPF_PROG_ATTACH, &attr, sizeof(attr));
  }
  
  int bpf_prog_detach(int target_fd, enum bpf_attach_type type)
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
529
  	memset(&attr, 0, sizeof(attr));
5dc880de6   Joe Stringer   tools lib bpf: Ad...
530
531
532
533
534
  	attr.target_fd	 = target_fd;
  	attr.attach_type = type;
  
  	return sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr));
  }
308488737   Alexei Starovoitov   tools/lib/bpf: ad...
535

244d20efd   Alexei Starovoitov   libbpf: introduce...
536
537
538
  int bpf_prog_detach2(int prog_fd, int target_fd, enum bpf_attach_type type)
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
539
  	memset(&attr, 0, sizeof(attr));
244d20efd   Alexei Starovoitov   libbpf: introduce...
540
541
542
543
544
545
  	attr.target_fd	 = target_fd;
  	attr.attach_bpf_fd = prog_fd;
  	attr.attach_type = type;
  
  	return sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr));
  }
cc4f864bb   Andrii Nakryiko   libbpf: Add suppo...
546
547
548
549
  int bpf_link_create(int prog_fd, int target_fd,
  		    enum bpf_attach_type attach_type,
  		    const struct bpf_link_create_opts *opts)
  {
a53590914   Toke Høiland-Jørgensen   libbpf: Add suppo...
550
  	__u32 target_btf_id, iter_info_len;
cc4f864bb   Andrii Nakryiko   libbpf: Add suppo...
551
552
553
554
  	union bpf_attr attr;
  
  	if (!OPTS_VALID(opts, bpf_link_create_opts))
  		return -EINVAL;
a53590914   Toke Høiland-Jørgensen   libbpf: Add suppo...
555
556
557
558
559
  	iter_info_len = OPTS_GET(opts, iter_info_len, 0);
  	target_btf_id = OPTS_GET(opts, target_btf_id, 0);
  
  	if (iter_info_len && target_btf_id)
  		return -EINVAL;
cc4f864bb   Andrii Nakryiko   libbpf: Add suppo...
560
561
562
563
  	memset(&attr, 0, sizeof(attr));
  	attr.link_create.prog_fd = prog_fd;
  	attr.link_create.target_fd = target_fd;
  	attr.link_create.attach_type = attach_type;
cd31039a7   Yonghong Song   tools/libbpf: Add...
564
  	attr.link_create.flags = OPTS_GET(opts, flags, 0);
a53590914   Toke Høiland-Jørgensen   libbpf: Add suppo...
565
566
567
568
569
570
571
572
  
  	if (iter_info_len) {
  		attr.link_create.iter_info =
  			ptr_to_u64(OPTS_GET(opts, iter_info, (void *)0));
  		attr.link_create.iter_info_len = iter_info_len;
  	} else if (target_btf_id) {
  		attr.link_create.target_btf_id = target_btf_id;
  	}
cc4f864bb   Andrii Nakryiko   libbpf: Add suppo...
573
574
575
  
  	return sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr));
  }
2e49527e5   Andrii Nakryiko   libbpf: Add bpf_l...
576
577
578
579
580
581
582
583
584
  int bpf_link_detach(int link_fd)
  {
  	union bpf_attr attr;
  
  	memset(&attr, 0, sizeof(attr));
  	attr.link_detach.link_fd = link_fd;
  
  	return sys_bpf(BPF_LINK_DETACH, &attr, sizeof(attr));
  }
cc4f864bb   Andrii Nakryiko   libbpf: Add suppo...
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
  int bpf_link_update(int link_fd, int new_prog_fd,
  		    const struct bpf_link_update_opts *opts)
  {
  	union bpf_attr attr;
  
  	if (!OPTS_VALID(opts, bpf_link_update_opts))
  		return -EINVAL;
  
  	memset(&attr, 0, sizeof(attr));
  	attr.link_update.link_fd = link_fd;
  	attr.link_update.new_prog_fd = new_prog_fd;
  	attr.link_update.flags = OPTS_GET(opts, flags, 0);
  	attr.link_update.old_prog_fd = OPTS_GET(opts, old_prog_fd, 0);
  
  	return sys_bpf(BPF_LINK_UPDATE, &attr, sizeof(attr));
  }
c09add2fb   Yonghong Song   tools/libbpf: Add...
601
602
603
604
605
606
607
608
609
  int bpf_iter_create(int link_fd)
  {
  	union bpf_attr attr;
  
  	memset(&attr, 0, sizeof(attr));
  	attr.iter_create.link_fd = link_fd;
  
  	return sys_bpf(BPF_ITER_CREATE, &attr, sizeof(attr));
  }
5d0cbf9b6   Alexei Starovoitov   libbpf: add suppo...
610
611
612
613
614
  int bpf_prog_query(int target_fd, enum bpf_attach_type type, __u32 query_flags,
  		   __u32 *attach_flags, __u32 *prog_ids, __u32 *prog_cnt)
  {
  	union bpf_attr attr;
  	int ret;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
615
  	memset(&attr, 0, sizeof(attr));
5d0cbf9b6   Alexei Starovoitov   libbpf: add suppo...
616
617
618
619
620
621
622
623
624
625
626
627
  	attr.query.target_fd	= target_fd;
  	attr.query.attach_type	= type;
  	attr.query.query_flags	= query_flags;
  	attr.query.prog_cnt	= *prog_cnt;
  	attr.query.prog_ids	= ptr_to_u64(prog_ids);
  
  	ret = sys_bpf(BPF_PROG_QUERY, &attr, sizeof(attr));
  	if (attach_flags)
  		*attach_flags = attr.query.attach_flags;
  	*prog_cnt = attr.query.prog_cnt;
  	return ret;
  }
308488737   Alexei Starovoitov   tools/lib/bpf: ad...
628
629
630
631
632
633
  int bpf_prog_test_run(int prog_fd, int repeat, void *data, __u32 size,
  		      void *data_out, __u32 *size_out, __u32 *retval,
  		      __u32 *duration)
  {
  	union bpf_attr attr;
  	int ret;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
634
  	memset(&attr, 0, sizeof(attr));
308488737   Alexei Starovoitov   tools/lib/bpf: ad...
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
  	attr.test.prog_fd = prog_fd;
  	attr.test.data_in = ptr_to_u64(data);
  	attr.test.data_out = ptr_to_u64(data_out);
  	attr.test.data_size_in = size;
  	attr.test.repeat = repeat;
  
  	ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr));
  	if (size_out)
  		*size_out = attr.test.data_size_out;
  	if (retval)
  		*retval = attr.test.retval;
  	if (duration)
  		*duration = attr.test.duration;
  	return ret;
  }
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
650

64a975913   Lorenz Bauer   libbpf: add bpf_p...
651
652
653
654
655
656
657
  int bpf_prog_test_run_xattr(struct bpf_prog_test_run_attr *test_attr)
  {
  	union bpf_attr attr;
  	int ret;
  
  	if (!test_attr->data_out && test_attr->data_size_out > 0)
  		return -EINVAL;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
658
  	memset(&attr, 0, sizeof(attr));
64a975913   Lorenz Bauer   libbpf: add bpf_p...
659
660
661
662
663
  	attr.test.prog_fd = test_attr->prog_fd;
  	attr.test.data_in = ptr_to_u64(test_attr->data_in);
  	attr.test.data_out = ptr_to_u64(test_attr->data_out);
  	attr.test.data_size_in = test_attr->data_size_in;
  	attr.test.data_size_out = test_attr->data_size_out;
5e903c656   Stanislav Fomichev   libbpf: add suppo...
664
665
666
667
  	attr.test.ctx_in = ptr_to_u64(test_attr->ctx_in);
  	attr.test.ctx_out = ptr_to_u64(test_attr->ctx_out);
  	attr.test.ctx_size_in = test_attr->ctx_size_in;
  	attr.test.ctx_size_out = test_attr->ctx_size_out;
64a975913   Lorenz Bauer   libbpf: add bpf_p...
668
669
670
671
  	attr.test.repeat = test_attr->repeat;
  
  	ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr));
  	test_attr->data_size_out = attr.test.data_size_out;
5e903c656   Stanislav Fomichev   libbpf: add suppo...
672
  	test_attr->ctx_size_out = attr.test.ctx_size_out;
64a975913   Lorenz Bauer   libbpf: add bpf_p...
673
674
675
676
  	test_attr->retval = attr.test.retval;
  	test_attr->duration = attr.test.duration;
  	return ret;
  }
88f7fe723   Song Liu   libbpf: Support t...
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
  int bpf_prog_test_run_opts(int prog_fd, struct bpf_test_run_opts *opts)
  {
  	union bpf_attr attr;
  	int ret;
  
  	if (!OPTS_VALID(opts, bpf_test_run_opts))
  		return -EINVAL;
  
  	memset(&attr, 0, sizeof(attr));
  	attr.test.prog_fd = prog_fd;
  	attr.test.cpu = OPTS_GET(opts, cpu, 0);
  	attr.test.flags = OPTS_GET(opts, flags, 0);
  	attr.test.repeat = OPTS_GET(opts, repeat, 0);
  	attr.test.duration = OPTS_GET(opts, duration, 0);
  	attr.test.ctx_size_in = OPTS_GET(opts, ctx_size_in, 0);
  	attr.test.ctx_size_out = OPTS_GET(opts, ctx_size_out, 0);
  	attr.test.data_size_in = OPTS_GET(opts, data_size_in, 0);
  	attr.test.data_size_out = OPTS_GET(opts, data_size_out, 0);
  	attr.test.ctx_in = ptr_to_u64(OPTS_GET(opts, ctx_in, NULL));
  	attr.test.ctx_out = ptr_to_u64(OPTS_GET(opts, ctx_out, NULL));
  	attr.test.data_in = ptr_to_u64(OPTS_GET(opts, data_in, NULL));
  	attr.test.data_out = ptr_to_u64(OPTS_GET(opts, data_out, NULL));
  
  	ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr));
  	OPTS_SET(opts, data_size_out, attr.test.data_size_out);
  	OPTS_SET(opts, ctx_size_out, attr.test.ctx_size_out);
  	OPTS_SET(opts, duration, attr.test.duration);
  	OPTS_SET(opts, retval, attr.test.retval);
  	return ret;
  }
a6e130c42   Quentin Monnet   libbpf: refactor ...
707
  static int bpf_obj_get_next_id(__u32 start_id, __u32 *next_id, int cmd)
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
708
709
710
  {
  	union bpf_attr attr;
  	int err;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
711
  	memset(&attr, 0, sizeof(attr));
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
712
  	attr.start_id = start_id;
a6e130c42   Quentin Monnet   libbpf: refactor ...
713
  	err = sys_bpf(cmd, &attr, sizeof(attr));
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
714
715
716
717
718
  	if (!err)
  		*next_id = attr.next_id;
  
  	return err;
  }
a6e130c42   Quentin Monnet   libbpf: refactor ...
719
  int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id)
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
720
  {
a6e130c42   Quentin Monnet   libbpf: refactor ...
721
722
  	return bpf_obj_get_next_id(start_id, next_id, BPF_PROG_GET_NEXT_ID);
  }
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
723

a6e130c42   Quentin Monnet   libbpf: refactor ...
724
725
726
  int bpf_map_get_next_id(__u32 start_id, __u32 *next_id)
  {
  	return bpf_obj_get_next_id(start_id, next_id, BPF_MAP_GET_NEXT_ID);
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
727
  }
09d7c2e32   Quentin Monnet   libbpf: add bpf_b...
728
729
730
731
  int bpf_btf_get_next_id(__u32 start_id, __u32 *next_id)
  {
  	return bpf_obj_get_next_id(start_id, next_id, BPF_BTF_GET_NEXT_ID);
  }
0dbc86683   Andrii Nakryiko   libbpf: Add low-l...
732
733
734
735
  int bpf_link_get_next_id(__u32 start_id, __u32 *next_id)
  {
  	return bpf_obj_get_next_id(start_id, next_id, BPF_LINK_GET_NEXT_ID);
  }
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
736
737
738
  int bpf_prog_get_fd_by_id(__u32 id)
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
739
  	memset(&attr, 0, sizeof(attr));
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
740
741
742
743
744
745
746
747
  	attr.prog_id = id;
  
  	return sys_bpf(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
  }
  
  int bpf_map_get_fd_by_id(__u32 id)
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
748
  	memset(&attr, 0, sizeof(attr));
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
749
750
751
752
  	attr.map_id = id;
  
  	return sys_bpf(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr));
  }
cd8b89280   Martin KaFai Lau   bpf: btf: Tests f...
753
754
755
  int bpf_btf_get_fd_by_id(__u32 id)
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
756
  	memset(&attr, 0, sizeof(attr));
cd8b89280   Martin KaFai Lau   bpf: btf: Tests f...
757
758
759
760
  	attr.btf_id = id;
  
  	return sys_bpf(BPF_BTF_GET_FD_BY_ID, &attr, sizeof(attr));
  }
0dbc86683   Andrii Nakryiko   libbpf: Add low-l...
761
762
763
764
765
766
767
768
769
770
771
  int bpf_link_get_fd_by_id(__u32 id)
  {
  	union bpf_attr attr;
  
  	memset(&attr, 0, sizeof(attr));
  	attr.link_id = id;
  
  	return sys_bpf(BPF_LINK_GET_FD_BY_ID, &attr, sizeof(attr));
  }
  
  int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len)
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
772
773
774
  {
  	union bpf_attr attr;
  	int err;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
775
  	memset(&attr, 0, sizeof(attr));
0dbc86683   Andrii Nakryiko   libbpf: Add low-l...
776
  	attr.info.bpf_fd = bpf_fd;
95b9afd39   Martin KaFai Lau   bpf: Test for bpf ID
777
778
779
780
781
782
783
784
785
  	attr.info.info_len = *info_len;
  	attr.info.info = ptr_to_u64(info);
  
  	err = sys_bpf(BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr));
  	if (!err)
  		*info_len = attr.info.info_len;
  
  	return err;
  }
949abbe88   Eric Leblond   libbpf: add funct...
786

a0fe3e574   Alexei Starovoitov   libbpf: add bpf_r...
787
788
789
  int bpf_raw_tracepoint_open(const char *name, int prog_fd)
  {
  	union bpf_attr attr;
1ad9cbb89   Andrii Nakryiko   tools/bpf: replac...
790
  	memset(&attr, 0, sizeof(attr));
a0fe3e574   Alexei Starovoitov   libbpf: add bpf_r...
791
792
793
794
795
  	attr.raw_tracepoint.name = ptr_to_u64(name);
  	attr.raw_tracepoint.prog_fd = prog_fd;
  
  	return sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
  }
b86042478   Andrii Nakryiko   libbpf: Remove as...
796
  int bpf_load_btf(const void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size,
8a138aed4   Martin KaFai Lau   bpf: btf: Add BTF...
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
  		 bool do_log)
  {
  	union bpf_attr attr = {};
  	int fd;
  
  	attr.btf = ptr_to_u64(btf);
  	attr.btf_size = btf_size;
  
  retry:
  	if (do_log && log_buf && log_buf_size) {
  		attr.btf_log_level = 1;
  		attr.btf_log_size = log_buf_size;
  		attr.btf_log_buf = ptr_to_u64(log_buf);
  	}
  
  	fd = sys_bpf(BPF_BTF_LOAD, &attr, sizeof(attr));
  	if (fd == -1 && !do_log && log_buf && log_buf_size) {
  		do_log = true;
  		goto retry;
  	}
  
  	return fd;
  }
30687ad94   Yonghong Song   tools/bpf: sync k...
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
  
  int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf, __u32 *buf_len,
  		      __u32 *prog_id, __u32 *fd_type, __u64 *probe_offset,
  		      __u64 *probe_addr)
  {
  	union bpf_attr attr = {};
  	int err;
  
  	attr.task_fd_query.pid = pid;
  	attr.task_fd_query.fd = fd;
  	attr.task_fd_query.flags = flags;
  	attr.task_fd_query.buf = ptr_to_u64(buf);
  	attr.task_fd_query.buf_len = *buf_len;
  
  	err = sys_bpf(BPF_TASK_FD_QUERY, &attr, sizeof(attr));
  	*buf_len = attr.task_fd_query.buf_len;
  	*prog_id = attr.task_fd_query.prog_id;
  	*fd_type = attr.task_fd_query.fd_type;
  	*probe_offset = attr.task_fd_query.probe_offset;
  	*probe_addr = attr.task_fd_query.probe_addr;
  
  	return err;
  }
0bee10671   Song Liu   libbpf: Add suppo...
843
844
845
846
847
848
849
850
851
852
  
  int bpf_enable_stats(enum bpf_stats_type type)
  {
  	union bpf_attr attr;
  
  	memset(&attr, 0, sizeof(attr));
  	attr.enable_stats.type = type;
  
  	return sys_bpf(BPF_ENABLE_STATS, &attr, sizeof(attr));
  }
5d23328dc   YiFei Zhu   libbpf: Add BPF_P...
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
  
  int bpf_prog_bind_map(int prog_fd, int map_fd,
  		      const struct bpf_prog_bind_opts *opts)
  {
  	union bpf_attr attr;
  
  	if (!OPTS_VALID(opts, bpf_prog_bind_opts))
  		return -EINVAL;
  
  	memset(&attr, 0, sizeof(attr));
  	attr.prog_bind_map.prog_fd = prog_fd;
  	attr.prog_bind_map.map_fd = map_fd;
  	attr.prog_bind_map.flags = OPTS_GET(opts, flags, 0);
  
  	return sys_bpf(BPF_PROG_BIND_MAP, &attr, sizeof(attr));
  }