• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (c) 2019-2020 Linux Test Project
4  */
5 
6 #define TST_NO_DEFAULT_MAIN
7 #include "tst_test.h"
8 #include "lapi/bpf.h"
9 #include "bpf_common.h"
10 
rlimit_bump_memlock(void)11 void rlimit_bump_memlock(void)
12 {
13 	struct rlimit memlock_r;
14 
15 	SAFE_GETRLIMIT(RLIMIT_MEMLOCK, &memlock_r);
16 	memlock_r.rlim_cur += BPF_MEMLOCK_ADD;
17 	tst_res(TINFO, "Raising RLIMIT_MEMLOCK to %ld",
18 		(long)memlock_r.rlim_cur);
19 
20 	if (memlock_r.rlim_cur <= memlock_r.rlim_max) {
21 		SAFE_SETRLIMIT(RLIMIT_MEMLOCK, &memlock_r);
22 	} else if ((geteuid() == 0)) {
23 		memlock_r.rlim_max += BPF_MEMLOCK_ADD;
24 		SAFE_SETRLIMIT(RLIMIT_MEMLOCK, &memlock_r);
25 	} else {
26 		tst_res(TINFO, "Can't raise RLIMIT_MEMLOCK, test may fail "
27 			"due to lack of max locked memory");
28 	}
29 }
30 
bpf_map_create(union bpf_attr * attr)31 int bpf_map_create(union bpf_attr *attr)
32 {
33 	int ret;
34 
35 	ret = TST_RETRY_FUNC(bpf(BPF_MAP_CREATE, attr, sizeof(*attr)),
36 		TST_RETVAL_GE0);
37 
38 	if (ret == -1) {
39 		if (errno == EPERM) {
40 			tst_res(TCONF, "Hint: check also /proc/sys/kernel/unprivileged_bpf_disabled");
41 			tst_brk(TCONF | TERRNO,
42 				"bpf() requires CAP_SYS_ADMIN on this system");
43 		} else {
44 			tst_brk(TBROK | TERRNO, "Failed to create array map");
45 		}
46 	}
47 
48 	return ret;
49 }
50 
bpf_init_prog_attr(union bpf_attr * attr,const struct bpf_insn * prog,size_t prog_size,char * log_buf,size_t log_size)51 void bpf_init_prog_attr(union bpf_attr *attr, const struct bpf_insn *prog,
52 	size_t prog_size, char *log_buf, size_t log_size)
53 {
54 	static struct bpf_insn *buf;
55 	static size_t buf_size;
56 	size_t prog_len = prog_size / sizeof(*prog);
57 
58 	/* all guarded buffers will be free()d automatically by LTP library */
59 	if (!buf || prog_size > buf_size) {
60 		buf = tst_alloc(prog_size);
61 		buf_size = prog_size;
62 	}
63 
64 	memcpy(buf, prog, prog_size);
65 	memset(attr, 0, sizeof(*attr));
66 	attr->prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
67 	attr->insns = ptr_to_u64(buf);
68 	attr->insn_cnt = prog_len;
69 	attr->license = ptr_to_u64("GPL");
70 	attr->log_buf = ptr_to_u64(log_buf);
71 	attr->log_size = log_size;
72 	attr->log_level = 1;
73 }
74 
bpf_load_prog(union bpf_attr * attr,const char * log)75 int bpf_load_prog(union bpf_attr *attr, const char *log)
76 {
77 	int ret;
78 
79 	ret = TST_RETRY_FUNC(bpf(BPF_PROG_LOAD, attr, sizeof(*attr)),
80 		TST_RETVAL_GE0);
81 
82 	if (ret >= 0) {
83 		tst_res(TPASS, "Loaded program");
84 		return ret;
85 	}
86 
87 	if (ret != -1)
88 		tst_brk(TBROK, "Invalid bpf() return value: %d", ret);
89 
90 	if (log[0] != 0)
91 		tst_brk(TBROK | TERRNO, "Failed verification: %s", log);
92 
93 	tst_brk(TBROK | TERRNO, "Failed to load program");
94 	return ret;
95 }
96