Linux Audio

Check our new training course

Loading...
v5.4
  1// SPDX-License-Identifier: GPL-2.0
  2#include <test_progs.h>
  3#include "cgroup_helpers.h"
  4
  5static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title)
  6{
  7	enum bpf_attach_type attach_type;
  8	enum bpf_prog_type prog_type;
  9	struct bpf_program *prog;
 10	int err;
 11
 12	err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
 13	if (err) {
 14		log_err("Failed to deduct types for %s BPF program", title);
 15		return -1;
 16	}
 17
 18	prog = bpf_object__find_program_by_title(obj, title);
 19	if (!prog) {
 20		log_err("Failed to find %s BPF program", title);
 21		return -1;
 22	}
 23
 24	err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd,
 25			      attach_type, BPF_F_ALLOW_MULTI);
 26	if (err) {
 27		log_err("Failed to attach %s BPF program", title);
 28		return -1;
 29	}
 30
 31	return 0;
 32}
 33
 34static int prog_detach(struct bpf_object *obj, int cgroup_fd, const char *title)
 35{
 36	enum bpf_attach_type attach_type;
 37	enum bpf_prog_type prog_type;
 38	struct bpf_program *prog;
 39	int err;
 40
 41	err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
 42	if (err)
 43		return -1;
 44
 45	prog = bpf_object__find_program_by_title(obj, title);
 46	if (!prog)
 47		return -1;
 48
 49	err = bpf_prog_detach2(bpf_program__fd(prog), cgroup_fd,
 50			       attach_type);
 51	if (err)
 52		return -1;
 53
 54	return 0;
 55}
 56
 57static int run_getsockopt_test(struct bpf_object *obj, int cg_parent,
 58			       int cg_child, int sock_fd)
 59{
 60	socklen_t optlen;
 61	__u8 buf;
 62	int err;
 63
 64	/* Set IP_TOS to the expected value (0x80). */
 65
 66	buf = 0x80;
 67	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
 68	if (err < 0) {
 69		log_err("Failed to call setsockopt(IP_TOS)");
 70		goto detach;
 71	}
 72
 73	buf = 0x00;
 74	optlen = 1;
 75	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
 76	if (err) {
 77		log_err("Failed to call getsockopt(IP_TOS)");
 78		goto detach;
 79	}
 80
 81	if (buf != 0x80) {
 82		log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf);
 83		err = -1;
 84		goto detach;
 85	}
 86
 87	/* Attach child program and make sure it returns new value:
 88	 * - kernel:      -> 0x80
 89	 * - child:  0x80 -> 0x90
 90	 */
 91
 92	err = prog_attach(obj, cg_child, "cgroup/getsockopt/child");
 93	if (err)
 94		goto detach;
 95
 96	buf = 0x00;
 97	optlen = 1;
 98	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
 99	if (err) {
100		log_err("Failed to call getsockopt(IP_TOS)");
101		goto detach;
102	}
103
104	if (buf != 0x90) {
105		log_err("Unexpected getsockopt 0x%x != 0x90", buf);
106		err = -1;
107		goto detach;
108	}
109
110	/* Attach parent program and make sure it returns new value:
111	 * - kernel:      -> 0x80
112	 * - child:  0x80 -> 0x90
113	 * - parent: 0x90 -> 0xA0
114	 */
115
116	err = prog_attach(obj, cg_parent, "cgroup/getsockopt/parent");
117	if (err)
118		goto detach;
119
120	buf = 0x00;
121	optlen = 1;
122	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
123	if (err) {
124		log_err("Failed to call getsockopt(IP_TOS)");
125		goto detach;
126	}
127
128	if (buf != 0xA0) {
129		log_err("Unexpected getsockopt 0x%x != 0xA0", buf);
130		err = -1;
131		goto detach;
132	}
133
134	/* Setting unexpected initial sockopt should return EPERM:
135	 * - kernel: -> 0x40
136	 * - child:  unexpected 0x40, EPERM
137	 * - parent: unexpected 0x40, EPERM
138	 */
139
140	buf = 0x40;
141	if (setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1) < 0) {
 
142		log_err("Failed to call setsockopt(IP_TOS)");
143		goto detach;
144	}
145
146	buf = 0x00;
147	optlen = 1;
148	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
149	if (!err) {
150		log_err("Unexpected success from getsockopt(IP_TOS)");
151		goto detach;
152	}
153
154	/* Detach child program and make sure we still get EPERM:
155	 * - kernel: -> 0x40
156	 * - parent: unexpected 0x40, EPERM
157	 */
158
159	err = prog_detach(obj, cg_child, "cgroup/getsockopt/child");
160	if (err) {
161		log_err("Failed to detach child program");
162		goto detach;
163	}
164
165	buf = 0x00;
166	optlen = 1;
167	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
168	if (!err) {
169		log_err("Unexpected success from getsockopt(IP_TOS)");
170		goto detach;
171	}
172
173	/* Set initial value to the one the parent program expects:
174	 * - kernel:      -> 0x90
175	 * - parent: 0x90 -> 0xA0
176	 */
177
178	buf = 0x90;
179	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
180	if (err < 0) {
181		log_err("Failed to call setsockopt(IP_TOS)");
182		goto detach;
183	}
184
185	buf = 0x00;
186	optlen = 1;
187	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
188	if (err) {
189		log_err("Failed to call getsockopt(IP_TOS)");
190		goto detach;
191	}
192
193	if (buf != 0xA0) {
194		log_err("Unexpected getsockopt 0x%x != 0xA0", buf);
195		err = -1;
196		goto detach;
197	}
198
199detach:
200	prog_detach(obj, cg_child, "cgroup/getsockopt/child");
201	prog_detach(obj, cg_parent, "cgroup/getsockopt/parent");
202
203	return err;
204}
205
206static int run_setsockopt_test(struct bpf_object *obj, int cg_parent,
207			       int cg_child, int sock_fd)
208{
209	socklen_t optlen;
210	__u8 buf;
211	int err;
212
213	/* Set IP_TOS to the expected value (0x80). */
214
215	buf = 0x80;
216	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
217	if (err < 0) {
218		log_err("Failed to call setsockopt(IP_TOS)");
219		goto detach;
220	}
221
222	buf = 0x00;
223	optlen = 1;
224	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
225	if (err) {
226		log_err("Failed to call getsockopt(IP_TOS)");
227		goto detach;
228	}
229
230	if (buf != 0x80) {
231		log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf);
232		err = -1;
233		goto detach;
234	}
235
236	/* Attach child program and make sure it adds 0x10. */
237
238	err = prog_attach(obj, cg_child, "cgroup/setsockopt");
239	if (err)
240		goto detach;
241
242	buf = 0x80;
243	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
244	if (err < 0) {
245		log_err("Failed to call setsockopt(IP_TOS)");
246		goto detach;
247	}
248
249	buf = 0x00;
250	optlen = 1;
251	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
252	if (err) {
253		log_err("Failed to call getsockopt(IP_TOS)");
254		goto detach;
255	}
256
257	if (buf != 0x80 + 0x10) {
258		log_err("Unexpected getsockopt 0x%x != 0x80 + 0x10", buf);
259		err = -1;
260		goto detach;
261	}
262
263	/* Attach parent program and make sure it adds another 0x10. */
264
265	err = prog_attach(obj, cg_parent, "cgroup/setsockopt");
266	if (err)
267		goto detach;
268
269	buf = 0x80;
270	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
271	if (err < 0) {
272		log_err("Failed to call setsockopt(IP_TOS)");
273		goto detach;
274	}
275
276	buf = 0x00;
277	optlen = 1;
278	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
279	if (err) {
280		log_err("Failed to call getsockopt(IP_TOS)");
281		goto detach;
282	}
283
284	if (buf != 0x80 + 2 * 0x10) {
285		log_err("Unexpected getsockopt 0x%x != 0x80 + 2 * 0x10", buf);
286		err = -1;
287		goto detach;
288	}
289
290detach:
291	prog_detach(obj, cg_child, "cgroup/setsockopt");
292	prog_detach(obj, cg_parent, "cgroup/setsockopt");
293
294	return err;
295}
296
297void test_sockopt_multi(void)
298{
299	struct bpf_prog_load_attr attr = {
300		.file = "./sockopt_multi.o",
301	};
302	int cg_parent = -1, cg_child = -1;
303	struct bpf_object *obj = NULL;
304	int sock_fd = -1;
305	int err = -1;
306	int ignored;
307
308	cg_parent = test__join_cgroup("/parent");
309	if (CHECK_FAIL(cg_parent < 0))
310		goto out;
311
312	cg_child = test__join_cgroup("/parent/child");
313	if (CHECK_FAIL(cg_child < 0))
314		goto out;
315
316	err = bpf_prog_load_xattr(&attr, &obj, &ignored);
317	if (CHECK_FAIL(err))
318		goto out;
319
320	sock_fd = socket(AF_INET, SOCK_STREAM, 0);
321	if (CHECK_FAIL(sock_fd < 0))
322		goto out;
323
324	CHECK_FAIL(run_getsockopt_test(obj, cg_parent, cg_child, sock_fd));
325	CHECK_FAIL(run_setsockopt_test(obj, cg_parent, cg_child, sock_fd));
326
327out:
328	close(sock_fd);
329	bpf_object__close(obj);
330	close(cg_child);
331	close(cg_parent);
332}
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0
  2#include <test_progs.h>
  3#include "cgroup_helpers.h"
  4
  5static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title)
  6{
  7	enum bpf_attach_type attach_type;
  8	enum bpf_prog_type prog_type;
  9	struct bpf_program *prog;
 10	int err;
 11
 12	err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
 13	if (err) {
 14		log_err("Failed to deduct types for %s BPF program", title);
 15		return -1;
 16	}
 17
 18	prog = bpf_object__find_program_by_title(obj, title);
 19	if (!prog) {
 20		log_err("Failed to find %s BPF program", title);
 21		return -1;
 22	}
 23
 24	err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd,
 25			      attach_type, BPF_F_ALLOW_MULTI);
 26	if (err) {
 27		log_err("Failed to attach %s BPF program", title);
 28		return -1;
 29	}
 30
 31	return 0;
 32}
 33
 34static int prog_detach(struct bpf_object *obj, int cgroup_fd, const char *title)
 35{
 36	enum bpf_attach_type attach_type;
 37	enum bpf_prog_type prog_type;
 38	struct bpf_program *prog;
 39	int err;
 40
 41	err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
 42	if (err)
 43		return -1;
 44
 45	prog = bpf_object__find_program_by_title(obj, title);
 46	if (!prog)
 47		return -1;
 48
 49	err = bpf_prog_detach2(bpf_program__fd(prog), cgroup_fd,
 50			       attach_type);
 51	if (err)
 52		return -1;
 53
 54	return 0;
 55}
 56
 57static int run_getsockopt_test(struct bpf_object *obj, int cg_parent,
 58			       int cg_child, int sock_fd)
 59{
 60	socklen_t optlen;
 61	__u8 buf;
 62	int err;
 63
 64	/* Set IP_TOS to the expected value (0x80). */
 65
 66	buf = 0x80;
 67	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
 68	if (err < 0) {
 69		log_err("Failed to call setsockopt(IP_TOS)");
 70		goto detach;
 71	}
 72
 73	buf = 0x00;
 74	optlen = 1;
 75	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
 76	if (err) {
 77		log_err("Failed to call getsockopt(IP_TOS)");
 78		goto detach;
 79	}
 80
 81	if (buf != 0x80) {
 82		log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf);
 83		err = -1;
 84		goto detach;
 85	}
 86
 87	/* Attach child program and make sure it returns new value:
 88	 * - kernel:      -> 0x80
 89	 * - child:  0x80 -> 0x90
 90	 */
 91
 92	err = prog_attach(obj, cg_child, "cgroup/getsockopt/child");
 93	if (err)
 94		goto detach;
 95
 96	buf = 0x00;
 97	optlen = 1;
 98	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
 99	if (err) {
100		log_err("Failed to call getsockopt(IP_TOS)");
101		goto detach;
102	}
103
104	if (buf != 0x90) {
105		log_err("Unexpected getsockopt 0x%x != 0x90", buf);
106		err = -1;
107		goto detach;
108	}
109
110	/* Attach parent program and make sure it returns new value:
111	 * - kernel:      -> 0x80
112	 * - child:  0x80 -> 0x90
113	 * - parent: 0x90 -> 0xA0
114	 */
115
116	err = prog_attach(obj, cg_parent, "cgroup/getsockopt/parent");
117	if (err)
118		goto detach;
119
120	buf = 0x00;
121	optlen = 1;
122	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
123	if (err) {
124		log_err("Failed to call getsockopt(IP_TOS)");
125		goto detach;
126	}
127
128	if (buf != 0xA0) {
129		log_err("Unexpected getsockopt 0x%x != 0xA0", buf);
130		err = -1;
131		goto detach;
132	}
133
134	/* Setting unexpected initial sockopt should return EPERM:
135	 * - kernel: -> 0x40
136	 * - child:  unexpected 0x40, EPERM
137	 * - parent: unexpected 0x40, EPERM
138	 */
139
140	buf = 0x40;
141	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
142	if (err < 0) {
143		log_err("Failed to call setsockopt(IP_TOS)");
144		goto detach;
145	}
146
147	buf = 0x00;
148	optlen = 1;
149	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
150	if (!err) {
151		log_err("Unexpected success from getsockopt(IP_TOS)");
152		goto detach;
153	}
154
155	/* Detach child program and make sure we still get EPERM:
156	 * - kernel: -> 0x40
157	 * - parent: unexpected 0x40, EPERM
158	 */
159
160	err = prog_detach(obj, cg_child, "cgroup/getsockopt/child");
161	if (err) {
162		log_err("Failed to detach child program");
163		goto detach;
164	}
165
166	buf = 0x00;
167	optlen = 1;
168	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
169	if (!err) {
170		log_err("Unexpected success from getsockopt(IP_TOS)");
171		goto detach;
172	}
173
174	/* Set initial value to the one the parent program expects:
175	 * - kernel:      -> 0x90
176	 * - parent: 0x90 -> 0xA0
177	 */
178
179	buf = 0x90;
180	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
181	if (err < 0) {
182		log_err("Failed to call setsockopt(IP_TOS)");
183		goto detach;
184	}
185
186	buf = 0x00;
187	optlen = 1;
188	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
189	if (err) {
190		log_err("Failed to call getsockopt(IP_TOS)");
191		goto detach;
192	}
193
194	if (buf != 0xA0) {
195		log_err("Unexpected getsockopt 0x%x != 0xA0", buf);
196		err = -1;
197		goto detach;
198	}
199
200detach:
201	prog_detach(obj, cg_child, "cgroup/getsockopt/child");
202	prog_detach(obj, cg_parent, "cgroup/getsockopt/parent");
203
204	return err;
205}
206
207static int run_setsockopt_test(struct bpf_object *obj, int cg_parent,
208			       int cg_child, int sock_fd)
209{
210	socklen_t optlen;
211	__u8 buf;
212	int err;
213
214	/* Set IP_TOS to the expected value (0x80). */
215
216	buf = 0x80;
217	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
218	if (err < 0) {
219		log_err("Failed to call setsockopt(IP_TOS)");
220		goto detach;
221	}
222
223	buf = 0x00;
224	optlen = 1;
225	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
226	if (err) {
227		log_err("Failed to call getsockopt(IP_TOS)");
228		goto detach;
229	}
230
231	if (buf != 0x80) {
232		log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf);
233		err = -1;
234		goto detach;
235	}
236
237	/* Attach child program and make sure it adds 0x10. */
238
239	err = prog_attach(obj, cg_child, "cgroup/setsockopt");
240	if (err)
241		goto detach;
242
243	buf = 0x80;
244	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
245	if (err < 0) {
246		log_err("Failed to call setsockopt(IP_TOS)");
247		goto detach;
248	}
249
250	buf = 0x00;
251	optlen = 1;
252	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
253	if (err) {
254		log_err("Failed to call getsockopt(IP_TOS)");
255		goto detach;
256	}
257
258	if (buf != 0x80 + 0x10) {
259		log_err("Unexpected getsockopt 0x%x != 0x80 + 0x10", buf);
260		err = -1;
261		goto detach;
262	}
263
264	/* Attach parent program and make sure it adds another 0x10. */
265
266	err = prog_attach(obj, cg_parent, "cgroup/setsockopt");
267	if (err)
268		goto detach;
269
270	buf = 0x80;
271	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
272	if (err < 0) {
273		log_err("Failed to call setsockopt(IP_TOS)");
274		goto detach;
275	}
276
277	buf = 0x00;
278	optlen = 1;
279	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
280	if (err) {
281		log_err("Failed to call getsockopt(IP_TOS)");
282		goto detach;
283	}
284
285	if (buf != 0x80 + 2 * 0x10) {
286		log_err("Unexpected getsockopt 0x%x != 0x80 + 2 * 0x10", buf);
287		err = -1;
288		goto detach;
289	}
290
291detach:
292	prog_detach(obj, cg_child, "cgroup/setsockopt");
293	prog_detach(obj, cg_parent, "cgroup/setsockopt");
294
295	return err;
296}
297
298void test_sockopt_multi(void)
299{
300	struct bpf_prog_load_attr attr = {
301		.file = "./sockopt_multi.o",
302	};
303	int cg_parent = -1, cg_child = -1;
304	struct bpf_object *obj = NULL;
305	int sock_fd = -1;
306	int err = -1;
307	int ignored;
308
309	cg_parent = test__join_cgroup("/parent");
310	if (CHECK_FAIL(cg_parent < 0))
311		goto out;
312
313	cg_child = test__join_cgroup("/parent/child");
314	if (CHECK_FAIL(cg_child < 0))
315		goto out;
316
317	err = bpf_prog_load_xattr(&attr, &obj, &ignored);
318	if (CHECK_FAIL(err))
319		goto out;
320
321	sock_fd = socket(AF_INET, SOCK_STREAM, 0);
322	if (CHECK_FAIL(sock_fd < 0))
323		goto out;
324
325	CHECK_FAIL(run_getsockopt_test(obj, cg_parent, cg_child, sock_fd));
326	CHECK_FAIL(run_setsockopt_test(obj, cg_parent, cg_child, sock_fd));
327
328out:
329	close(sock_fd);
330	bpf_object__close(obj);
331	close(cg_child);
332	close(cg_parent);
333}