xref: /openbmc/linux/tools/testing/selftests/bpf/test_progs.c (revision abade675e02e1b73da0c20ffaf08fbe309038298)
1 /* Copyright (c) 2017 Facebook
2  *
3  * This program is free software; you can redistribute it and/or
4  * modify it under the terms of version 2 of the GNU General Public
5  * License as published by the Free Software Foundation.
6  */
7 #include "test_progs.h"
8 #include "bpf_rlimit.h"
9 
10 int error_cnt, pass_cnt;
11 bool jit_enabled;
12 bool verifier_stats = false;
13 
14 struct ipv4_packet pkt_v4 = {
15 	.eth.h_proto = __bpf_constant_htons(ETH_P_IP),
16 	.iph.ihl = 5,
17 	.iph.protocol = IPPROTO_TCP,
18 	.iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
19 	.tcp.urg_ptr = 123,
20 	.tcp.doff = 5,
21 };
22 
23 struct ipv6_packet pkt_v6 = {
24 	.eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
25 	.iph.nexthdr = IPPROTO_TCP,
26 	.iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
27 	.tcp.urg_ptr = 123,
28 	.tcp.doff = 5,
29 };
30 
31 int bpf_find_map(const char *test, struct bpf_object *obj, const char *name)
32 {
33 	struct bpf_map *map;
34 
35 	map = bpf_object__find_map_by_name(obj, name);
36 	if (!map) {
37 		printf("%s:FAIL:map '%s' not found\n", test, name);
38 		error_cnt++;
39 		return -1;
40 	}
41 	return bpf_map__fd(map);
42 }
43 
44 static bool is_jit_enabled(void)
45 {
46 	const char *jit_sysctl = "/proc/sys/net/core/bpf_jit_enable";
47 	bool enabled = false;
48 	int sysctl_fd;
49 
50 	sysctl_fd = open(jit_sysctl, 0, O_RDONLY);
51 	if (sysctl_fd != -1) {
52 		char tmpc;
53 
54 		if (read(sysctl_fd, &tmpc, sizeof(tmpc)) == 1)
55 			enabled = (tmpc != '0');
56 		close(sysctl_fd);
57 	}
58 
59 	return enabled;
60 }
61 
62 int compare_map_keys(int map1_fd, int map2_fd)
63 {
64 	__u32 key, next_key;
65 	char val_buf[PERF_MAX_STACK_DEPTH *
66 		     sizeof(struct bpf_stack_build_id)];
67 	int err;
68 
69 	err = bpf_map_get_next_key(map1_fd, NULL, &key);
70 	if (err)
71 		return err;
72 	err = bpf_map_lookup_elem(map2_fd, &key, val_buf);
73 	if (err)
74 		return err;
75 
76 	while (bpf_map_get_next_key(map1_fd, &key, &next_key) == 0) {
77 		err = bpf_map_lookup_elem(map2_fd, &next_key, val_buf);
78 		if (err)
79 			return err;
80 
81 		key = next_key;
82 	}
83 	if (errno != ENOENT)
84 		return -1;
85 
86 	return 0;
87 }
88 
89 int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len)
90 {
91 	__u32 key, next_key, *cur_key_p, *next_key_p;
92 	char *val_buf1, *val_buf2;
93 	int i, err = 0;
94 
95 	val_buf1 = malloc(stack_trace_len);
96 	val_buf2 = malloc(stack_trace_len);
97 	cur_key_p = NULL;
98 	next_key_p = &key;
99 	while (bpf_map_get_next_key(smap_fd, cur_key_p, next_key_p) == 0) {
100 		err = bpf_map_lookup_elem(smap_fd, next_key_p, val_buf1);
101 		if (err)
102 			goto out;
103 		err = bpf_map_lookup_elem(amap_fd, next_key_p, val_buf2);
104 		if (err)
105 			goto out;
106 		for (i = 0; i < stack_trace_len; i++) {
107 			if (val_buf1[i] != val_buf2[i]) {
108 				err = -1;
109 				goto out;
110 			}
111 		}
112 		key = *next_key_p;
113 		cur_key_p = &key;
114 		next_key_p = &next_key;
115 	}
116 	if (errno != ENOENT)
117 		err = -1;
118 
119 out:
120 	free(val_buf1);
121 	free(val_buf2);
122 	return err;
123 }
124 
125 int extract_build_id(char *build_id, size_t size)
126 {
127 	FILE *fp;
128 	char *line = NULL;
129 	size_t len = 0;
130 
131 	fp = popen("readelf -n ./urandom_read | grep 'Build ID'", "r");
132 	if (fp == NULL)
133 		return -1;
134 
135 	if (getline(&line, &len, fp) == -1)
136 		goto err;
137 	fclose(fp);
138 
139 	if (len > size)
140 		len = size;
141 	memcpy(build_id, line, len);
142 	build_id[len] = '\0';
143 	return 0;
144 err:
145 	fclose(fp);
146 	return -1;
147 }
148 
149 void *spin_lock_thread(void *arg)
150 {
151 	__u32 duration, retval;
152 	int err, prog_fd = *(u32 *) arg;
153 
154 	err = bpf_prog_test_run(prog_fd, 10000, &pkt_v4, sizeof(pkt_v4),
155 				NULL, NULL, &retval, &duration);
156 	CHECK(err || retval, "",
157 	      "err %d errno %d retval %d duration %d\n",
158 	      err, errno, retval, duration);
159 	pthread_exit(arg);
160 }
161 
162 #define DECLARE
163 #include <prog_tests/tests.h>
164 #undef DECLARE
165 
166 int main(int ac, char **av)
167 {
168 	srand(time(NULL));
169 
170 	jit_enabled = is_jit_enabled();
171 
172 	if (ac == 2 && strcmp(av[1], "-s") == 0)
173 		verifier_stats = true;
174 
175 #define CALL
176 #include <prog_tests/tests.h>
177 #undef CALL
178 
179 	printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt);
180 	return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS;
181 }
182