xref: /linux/tools/lib/bpf/bpf.c (revision cd65cd95128781ca59d06611270fcbd9b4a7cf8d)
1 // SPDX-License-Identifier: LGPL-2.1
2 
3 /*
4  * common eBPF ELF operations.
5  *
6  * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
7  * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
8  * Copyright (C) 2015 Huawei Inc.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation;
13  * version 2.1 of the License (not later!)
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this program; if not,  see <http://www.gnu.org/licenses>
22  */
23 
24 #include <stdlib.h>
25 #include <memory.h>
26 #include <unistd.h>
27 #include <asm/unistd.h>
28 #include <linux/bpf.h>
29 #include "bpf.h"
30 #include "libbpf.h"
31 #include "nlattr.h"
32 #include <linux/rtnetlink.h>
33 #include <linux/if_link.h>
34 #include <sys/socket.h>
35 #include <errno.h>
36 
37 #ifndef SOL_NETLINK
38 #define SOL_NETLINK 270
39 #endif
40 
41 /*
42  * When building perf, unistd.h is overridden. __NR_bpf is
43  * required to be defined explicitly.
44  */
45 #ifndef __NR_bpf
46 # if defined(__i386__)
47 #  define __NR_bpf 357
48 # elif defined(__x86_64__)
49 #  define __NR_bpf 321
50 # elif defined(__aarch64__)
51 #  define __NR_bpf 280
52 # elif defined(__sparc__)
53 #  define __NR_bpf 349
54 # elif defined(__s390__)
55 #  define __NR_bpf 351
56 # else
57 #  error __NR_bpf not defined. libbpf does not support your arch.
58 # endif
59 #endif
60 
61 #ifndef min
62 #define min(x, y) ((x) < (y) ? (x) : (y))
63 #endif
64 
65 static inline __u64 ptr_to_u64(const void *ptr)
66 {
67 	return (__u64) (unsigned long) ptr;
68 }
69 
70 static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
71 			  unsigned int size)
72 {
73 	return syscall(__NR_bpf, cmd, attr, size);
74 }
75 
76 int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr)
77 {
78 	__u32 name_len = create_attr->name ? strlen(create_attr->name) : 0;
79 	union bpf_attr attr;
80 
81 	memset(&attr, '\0', sizeof(attr));
82 
83 	attr.map_type = create_attr->map_type;
84 	attr.key_size = create_attr->key_size;
85 	attr.value_size = create_attr->value_size;
86 	attr.max_entries = create_attr->max_entries;
87 	attr.map_flags = create_attr->map_flags;
88 	memcpy(attr.map_name, create_attr->name,
89 	       min(name_len, BPF_OBJ_NAME_LEN - 1));
90 	attr.numa_node = create_attr->numa_node;
91 	attr.btf_fd = create_attr->btf_fd;
92 	attr.btf_key_id = create_attr->btf_key_id;
93 	attr.btf_value_id = create_attr->btf_value_id;
94 
95 	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
96 }
97 
98 int bpf_create_map_node(enum bpf_map_type map_type, const char *name,
99 			int key_size, int value_size, int max_entries,
100 			__u32 map_flags, int node)
101 {
102 	struct bpf_create_map_attr map_attr = {};
103 
104 	map_attr.name = name;
105 	map_attr.map_type = map_type;
106 	map_attr.map_flags = map_flags;
107 	map_attr.key_size = key_size;
108 	map_attr.value_size = value_size;
109 	map_attr.max_entries = max_entries;
110 	if (node >= 0) {
111 		map_attr.numa_node = node;
112 		map_attr.map_flags |= BPF_F_NUMA_NODE;
113 	}
114 
115 	return bpf_create_map_xattr(&map_attr);
116 }
117 
118 int bpf_create_map(enum bpf_map_type map_type, int key_size,
119 		   int value_size, int max_entries, __u32 map_flags)
120 {
121 	struct bpf_create_map_attr map_attr = {};
122 
123 	map_attr.map_type = map_type;
124 	map_attr.map_flags = map_flags;
125 	map_attr.key_size = key_size;
126 	map_attr.value_size = value_size;
127 	map_attr.max_entries = max_entries;
128 
129 	return bpf_create_map_xattr(&map_attr);
130 }
131 
132 int bpf_create_map_name(enum bpf_map_type map_type, const char *name,
133 			int key_size, int value_size, int max_entries,
134 			__u32 map_flags)
135 {
136 	struct bpf_create_map_attr map_attr = {};
137 
138 	map_attr.name = name;
139 	map_attr.map_type = map_type;
140 	map_attr.map_flags = map_flags;
141 	map_attr.key_size = key_size;
142 	map_attr.value_size = value_size;
143 	map_attr.max_entries = max_entries;
144 
145 	return bpf_create_map_xattr(&map_attr);
146 }
147 
148 int bpf_create_map_in_map_node(enum bpf_map_type map_type, const char *name,
149 			       int key_size, int inner_map_fd, int max_entries,
150 			       __u32 map_flags, int node)
151 {
152 	__u32 name_len = name ? strlen(name) : 0;
153 	union bpf_attr attr;
154 
155 	memset(&attr, '\0', sizeof(attr));
156 
157 	attr.map_type = map_type;
158 	attr.key_size = key_size;
159 	attr.value_size = 4;
160 	attr.inner_map_fd = inner_map_fd;
161 	attr.max_entries = max_entries;
162 	attr.map_flags = map_flags;
163 	memcpy(attr.map_name, name, min(name_len, BPF_OBJ_NAME_LEN - 1));
164 
165 	if (node >= 0) {
166 		attr.map_flags |= BPF_F_NUMA_NODE;
167 		attr.numa_node = node;
168 	}
169 
170 	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
171 }
172 
173 int bpf_create_map_in_map(enum bpf_map_type map_type, const char *name,
174 			  int key_size, int inner_map_fd, int max_entries,
175 			  __u32 map_flags)
176 {
177 	return bpf_create_map_in_map_node(map_type, name, key_size,
178 					  inner_map_fd, max_entries, map_flags,
179 					  -1);
180 }
181 
182 int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
183 			   char *log_buf, size_t log_buf_sz)
184 {
185 	union bpf_attr attr;
186 	__u32 name_len;
187 	int fd;
188 
189 	if (!load_attr)
190 		return -EINVAL;
191 
192 	name_len = load_attr->name ? strlen(load_attr->name) : 0;
193 
194 	bzero(&attr, sizeof(attr));
195 	attr.prog_type = load_attr->prog_type;
196 	attr.expected_attach_type = load_attr->expected_attach_type;
197 	attr.insn_cnt = (__u32)load_attr->insns_cnt;
198 	attr.insns = ptr_to_u64(load_attr->insns);
199 	attr.license = ptr_to_u64(load_attr->license);
200 	attr.log_buf = ptr_to_u64(NULL);
201 	attr.log_size = 0;
202 	attr.log_level = 0;
203 	attr.kern_version = load_attr->kern_version;
204 	memcpy(attr.prog_name, load_attr->name,
205 	       min(name_len, BPF_OBJ_NAME_LEN - 1));
206 
207 	fd = sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
208 	if (fd >= 0 || !log_buf || !log_buf_sz)
209 		return fd;
210 
211 	/* Try again with log */
212 	attr.log_buf = ptr_to_u64(log_buf);
213 	attr.log_size = log_buf_sz;
214 	attr.log_level = 1;
215 	log_buf[0] = 0;
216 	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
217 }
218 
219 int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
220 		     size_t insns_cnt, const char *license,
221 		     __u32 kern_version, char *log_buf,
222 		     size_t log_buf_sz)
223 {
224 	struct bpf_load_program_attr load_attr;
225 
226 	memset(&load_attr, 0, sizeof(struct bpf_load_program_attr));
227 	load_attr.prog_type = type;
228 	load_attr.expected_attach_type = 0;
229 	load_attr.name = NULL;
230 	load_attr.insns = insns;
231 	load_attr.insns_cnt = insns_cnt;
232 	load_attr.license = license;
233 	load_attr.kern_version = kern_version;
234 
235 	return bpf_load_program_xattr(&load_attr, log_buf, log_buf_sz);
236 }
237 
238 int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns,
239 		       size_t insns_cnt, int strict_alignment,
240 		       const char *license, __u32 kern_version,
241 		       char *log_buf, size_t log_buf_sz, int log_level)
242 {
243 	union bpf_attr attr;
244 
245 	bzero(&attr, sizeof(attr));
246 	attr.prog_type = type;
247 	attr.insn_cnt = (__u32)insns_cnt;
248 	attr.insns = ptr_to_u64(insns);
249 	attr.license = ptr_to_u64(license);
250 	attr.log_buf = ptr_to_u64(log_buf);
251 	attr.log_size = log_buf_sz;
252 	attr.log_level = log_level;
253 	log_buf[0] = 0;
254 	attr.kern_version = kern_version;
255 	attr.prog_flags = strict_alignment ? BPF_F_STRICT_ALIGNMENT : 0;
256 
257 	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
258 }
259 
260 int bpf_map_update_elem(int fd, const void *key, const void *value,
261 			__u64 flags)
262 {
263 	union bpf_attr attr;
264 
265 	bzero(&attr, sizeof(attr));
266 	attr.map_fd = fd;
267 	attr.key = ptr_to_u64(key);
268 	attr.value = ptr_to_u64(value);
269 	attr.flags = flags;
270 
271 	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
272 }
273 
274 int bpf_map_lookup_elem(int fd, const void *key, void *value)
275 {
276 	union bpf_attr attr;
277 
278 	bzero(&attr, sizeof(attr));
279 	attr.map_fd = fd;
280 	attr.key = ptr_to_u64(key);
281 	attr.value = ptr_to_u64(value);
282 
283 	return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
284 }
285 
286 int bpf_map_delete_elem(int fd, const void *key)
287 {
288 	union bpf_attr attr;
289 
290 	bzero(&attr, sizeof(attr));
291 	attr.map_fd = fd;
292 	attr.key = ptr_to_u64(key);
293 
294 	return sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
295 }
296 
297 int bpf_map_get_next_key(int fd, const void *key, void *next_key)
298 {
299 	union bpf_attr attr;
300 
301 	bzero(&attr, sizeof(attr));
302 	attr.map_fd = fd;
303 	attr.key = ptr_to_u64(key);
304 	attr.next_key = ptr_to_u64(next_key);
305 
306 	return sys_bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
307 }
308 
309 int bpf_obj_pin(int fd, const char *pathname)
310 {
311 	union bpf_attr attr;
312 
313 	bzero(&attr, sizeof(attr));
314 	attr.pathname = ptr_to_u64((void *)pathname);
315 	attr.bpf_fd = fd;
316 
317 	return sys_bpf(BPF_OBJ_PIN, &attr, sizeof(attr));
318 }
319 
320 int bpf_obj_get(const char *pathname)
321 {
322 	union bpf_attr attr;
323 
324 	bzero(&attr, sizeof(attr));
325 	attr.pathname = ptr_to_u64((void *)pathname);
326 
327 	return sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr));
328 }
329 
330 int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type,
331 		    unsigned int flags)
332 {
333 	union bpf_attr attr;
334 
335 	bzero(&attr, sizeof(attr));
336 	attr.target_fd	   = target_fd;
337 	attr.attach_bpf_fd = prog_fd;
338 	attr.attach_type   = type;
339 	attr.attach_flags  = flags;
340 
341 	return sys_bpf(BPF_PROG_ATTACH, &attr, sizeof(attr));
342 }
343 
344 int bpf_prog_detach(int target_fd, enum bpf_attach_type type)
345 {
346 	union bpf_attr attr;
347 
348 	bzero(&attr, sizeof(attr));
349 	attr.target_fd	 = target_fd;
350 	attr.attach_type = type;
351 
352 	return sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr));
353 }
354 
355 int bpf_prog_detach2(int prog_fd, int target_fd, enum bpf_attach_type type)
356 {
357 	union bpf_attr attr;
358 
359 	bzero(&attr, sizeof(attr));
360 	attr.target_fd	 = target_fd;
361 	attr.attach_bpf_fd = prog_fd;
362 	attr.attach_type = type;
363 
364 	return sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr));
365 }
366 
367 int bpf_prog_query(int target_fd, enum bpf_attach_type type, __u32 query_flags,
368 		   __u32 *attach_flags, __u32 *prog_ids, __u32 *prog_cnt)
369 {
370 	union bpf_attr attr;
371 	int ret;
372 
373 	bzero(&attr, sizeof(attr));
374 	attr.query.target_fd	= target_fd;
375 	attr.query.attach_type	= type;
376 	attr.query.query_flags	= query_flags;
377 	attr.query.prog_cnt	= *prog_cnt;
378 	attr.query.prog_ids	= ptr_to_u64(prog_ids);
379 
380 	ret = sys_bpf(BPF_PROG_QUERY, &attr, sizeof(attr));
381 	if (attach_flags)
382 		*attach_flags = attr.query.attach_flags;
383 	*prog_cnt = attr.query.prog_cnt;
384 	return ret;
385 }
386 
387 int bpf_prog_test_run(int prog_fd, int repeat, void *data, __u32 size,
388 		      void *data_out, __u32 *size_out, __u32 *retval,
389 		      __u32 *duration)
390 {
391 	union bpf_attr attr;
392 	int ret;
393 
394 	bzero(&attr, sizeof(attr));
395 	attr.test.prog_fd = prog_fd;
396 	attr.test.data_in = ptr_to_u64(data);
397 	attr.test.data_out = ptr_to_u64(data_out);
398 	attr.test.data_size_in = size;
399 	attr.test.repeat = repeat;
400 
401 	ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr));
402 	if (size_out)
403 		*size_out = attr.test.data_size_out;
404 	if (retval)
405 		*retval = attr.test.retval;
406 	if (duration)
407 		*duration = attr.test.duration;
408 	return ret;
409 }
410 
411 int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id)
412 {
413 	union bpf_attr attr;
414 	int err;
415 
416 	bzero(&attr, sizeof(attr));
417 	attr.start_id = start_id;
418 
419 	err = sys_bpf(BPF_PROG_GET_NEXT_ID, &attr, sizeof(attr));
420 	if (!err)
421 		*next_id = attr.next_id;
422 
423 	return err;
424 }
425 
426 int bpf_map_get_next_id(__u32 start_id, __u32 *next_id)
427 {
428 	union bpf_attr attr;
429 	int err;
430 
431 	bzero(&attr, sizeof(attr));
432 	attr.start_id = start_id;
433 
434 	err = sys_bpf(BPF_MAP_GET_NEXT_ID, &attr, sizeof(attr));
435 	if (!err)
436 		*next_id = attr.next_id;
437 
438 	return err;
439 }
440 
441 int bpf_prog_get_fd_by_id(__u32 id)
442 {
443 	union bpf_attr attr;
444 
445 	bzero(&attr, sizeof(attr));
446 	attr.prog_id = id;
447 
448 	return sys_bpf(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
449 }
450 
451 int bpf_map_get_fd_by_id(__u32 id)
452 {
453 	union bpf_attr attr;
454 
455 	bzero(&attr, sizeof(attr));
456 	attr.map_id = id;
457 
458 	return sys_bpf(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr));
459 }
460 
461 int bpf_btf_get_fd_by_id(__u32 id)
462 {
463 	union bpf_attr attr;
464 
465 	bzero(&attr, sizeof(attr));
466 	attr.btf_id = id;
467 
468 	return sys_bpf(BPF_BTF_GET_FD_BY_ID, &attr, sizeof(attr));
469 }
470 
471 int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)
472 {
473 	union bpf_attr attr;
474 	int err;
475 
476 	bzero(&attr, sizeof(attr));
477 	attr.info.bpf_fd = prog_fd;
478 	attr.info.info_len = *info_len;
479 	attr.info.info = ptr_to_u64(info);
480 
481 	err = sys_bpf(BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr));
482 	if (!err)
483 		*info_len = attr.info.info_len;
484 
485 	return err;
486 }
487 
488 int bpf_raw_tracepoint_open(const char *name, int prog_fd)
489 {
490 	union bpf_attr attr;
491 
492 	bzero(&attr, sizeof(attr));
493 	attr.raw_tracepoint.name = ptr_to_u64(name);
494 	attr.raw_tracepoint.prog_fd = prog_fd;
495 
496 	return sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
497 }
498 
499 int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
500 {
501 	struct sockaddr_nl sa;
502 	int sock, seq = 0, len, ret = -1;
503 	char buf[4096];
504 	struct nlattr *nla, *nla_xdp;
505 	struct {
506 		struct nlmsghdr  nh;
507 		struct ifinfomsg ifinfo;
508 		char             attrbuf[64];
509 	} req;
510 	struct nlmsghdr *nh;
511 	struct nlmsgerr *err;
512 	socklen_t addrlen;
513 	int one = 1;
514 
515 	memset(&sa, 0, sizeof(sa));
516 	sa.nl_family = AF_NETLINK;
517 
518 	sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
519 	if (sock < 0) {
520 		return -errno;
521 	}
522 
523 	if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK,
524 		       &one, sizeof(one)) < 0) {
525 		fprintf(stderr, "Netlink error reporting not supported\n");
526 	}
527 
528 	if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
529 		ret = -errno;
530 		goto cleanup;
531 	}
532 
533 	addrlen = sizeof(sa);
534 	if (getsockname(sock, (struct sockaddr *)&sa, &addrlen) < 0) {
535 		ret = -errno;
536 		goto cleanup;
537 	}
538 
539 	if (addrlen != sizeof(sa)) {
540 		ret = -LIBBPF_ERRNO__INTERNAL;
541 		goto cleanup;
542 	}
543 
544 	memset(&req, 0, sizeof(req));
545 	req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
546 	req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
547 	req.nh.nlmsg_type = RTM_SETLINK;
548 	req.nh.nlmsg_pid = 0;
549 	req.nh.nlmsg_seq = ++seq;
550 	req.ifinfo.ifi_family = AF_UNSPEC;
551 	req.ifinfo.ifi_index = ifindex;
552 
553 	/* started nested attribute for XDP */
554 	nla = (struct nlattr *)(((char *)&req)
555 				+ NLMSG_ALIGN(req.nh.nlmsg_len));
556 	nla->nla_type = NLA_F_NESTED | IFLA_XDP;
557 	nla->nla_len = NLA_HDRLEN;
558 
559 	/* add XDP fd */
560 	nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
561 	nla_xdp->nla_type = IFLA_XDP_FD;
562 	nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
563 	memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
564 	nla->nla_len += nla_xdp->nla_len;
565 
566 	/* if user passed in any flags, add those too */
567 	if (flags) {
568 		nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
569 		nla_xdp->nla_type = IFLA_XDP_FLAGS;
570 		nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
571 		memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
572 		nla->nla_len += nla_xdp->nla_len;
573 	}
574 
575 	req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
576 
577 	if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
578 		ret = -errno;
579 		goto cleanup;
580 	}
581 
582 	len = recv(sock, buf, sizeof(buf), 0);
583 	if (len < 0) {
584 		ret = -errno;
585 		goto cleanup;
586 	}
587 
588 	for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
589 	     nh = NLMSG_NEXT(nh, len)) {
590 		if (nh->nlmsg_pid != sa.nl_pid) {
591 			ret = -LIBBPF_ERRNO__WRNGPID;
592 			goto cleanup;
593 		}
594 		if (nh->nlmsg_seq != seq) {
595 			ret = -LIBBPF_ERRNO__INVSEQ;
596 			goto cleanup;
597 		}
598 		switch (nh->nlmsg_type) {
599 		case NLMSG_ERROR:
600 			err = (struct nlmsgerr *)NLMSG_DATA(nh);
601 			if (!err->error)
602 				continue;
603 			ret = err->error;
604 			nla_dump_errormsg(nh);
605 			goto cleanup;
606 		case NLMSG_DONE:
607 			break;
608 		default:
609 			break;
610 		}
611 	}
612 
613 	ret = 0;
614 
615 cleanup:
616 	close(sock);
617 	return ret;
618 }
619 
620 int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size,
621 		 bool do_log)
622 {
623 	union bpf_attr attr = {};
624 	int fd;
625 
626 	attr.btf = ptr_to_u64(btf);
627 	attr.btf_size = btf_size;
628 
629 retry:
630 	if (do_log && log_buf && log_buf_size) {
631 		attr.btf_log_level = 1;
632 		attr.btf_log_size = log_buf_size;
633 		attr.btf_log_buf = ptr_to_u64(log_buf);
634 	}
635 
636 	fd = sys_bpf(BPF_BTF_LOAD, &attr, sizeof(attr));
637 	if (fd == -1 && !do_log && log_buf && log_buf_size) {
638 		do_log = true;
639 		goto retry;
640 	}
641 
642 	return fd;
643 }
644